自定義的View
自定義的控件有的是View和ViewGroup。這裏先練一下自定義的View,說到自定義的View,即利用主線程對UI界面進行繪製,自定義的View自然要繼承與View,其中要重寫OnMeasure()(測量畫布的寬和高的方法)和OnDraw()(繪製的方法Canvas畫布),還有要實現兩個構造器分別是
View(Content content),View(Content content,AttributeSet attra)
繪製簡單的一個表
在activity_main.xml中引用自定義的View時要將自定義的View的所在位置全稱寫出來,activity_main.xml如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<com.example.administrator.canvas.widget.MyView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
MyView.java自定義的View寫在另一個繼承於View的類裏,
public class MyView extends View {
private int width;
private int height;
private Paint mPaintLine;
private Paint mPaintCircle;
private Paint mPaintText;
private Calendar mCalendar;
private Paint mPaintMinute;
private Paint mPaintHour;
private Paint mPaintSecond;
private static final int HANDLE_SECOND=0;
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch(msg.what){
case HANDLE_SECOND:
mCalendar=Calendar.getInstance();
invalidate();//告訴UI主線程重新繪製
handler.sendEmptyMessageDelayed(HANDLE_SECOND, 1000);
break;
}
}
};
public MyView(Context context) {
//創建視圖時使用的簡單構造函數。
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
mCalendar=Calendar.getInstance();
//畫線的畫筆
mPaintLine =new Paint();
mPaintLine.setColor(Color.RED);//設置顯得顏色
mPaintLine.setStrokeWidth(10);//設置線的寬度
//畫圓的畫筆
mPaintCircle=new Paint();
mPaintCircle.setStrokeWidth(10);//設置線的寬度
mPaintCircle.setColor(Color.GREEN);//設置線的顏色
mPaintCircle.setStyle(Paint.Style.STROKE);//設置圓的空心
//寫字的畫筆
mPaintText=new Paint();
mPaintText.setTextSize(30);
mPaintText.setColor(Color.BLACK);
mPaintText.setTextAlign(Paint.Align.CENTER);
//畫分針的畫筆
mPaintMinute=new Paint();
mPaintMinute.setStrokeWidth(10);
mPaintMinute.setColor(Color.YELLOW);
//畫時針的畫筆
mPaintHour=new Paint();
mPaintHour.setStrokeWidth(15);
mPaintHour.setColor(Color.GREEN);
//畫秒針的畫筆
mPaintSecond=new Paint();
mPaintSecond.setColor(Color.RED);
mPaintSecond.setStrokeWidth(5);
//設置秒針走動
handler.sendEmptyMessageDelayed(HANDLE_SECOND, 2000);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width=getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
height=getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);
setMeasuredDimension(width,height);//設置畫布的大小,長和寬
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//是由UI主線程自動調用,只需要在此繪製即可
// canvas.drawLine(0,0,300,300,mPaintLine);
// canvas.drawCircle(300,300,100,mPaintCircle);
canvas.drawCircle(width/2,height/2,300,mPaintCircle);
canvas.drawCircle(width/2,height/2,10,mPaintCircle);
//繪製錶盤的刻度
for (int i=1;i<=12;i++){
// canvas.save();
canvas.rotate(360/12,width/2,height/2);
canvas.drawLine(width/2,height/2-300,width/2,height/2-270,mPaintLine);
canvas.drawText(""+i,width/2,height/2-240,mPaintText);
// canvas.restore();
}
int minute=mCalendar.get(Calendar.MINUTE);
int hour=mCalendar.get(Calendar.HOUR);
int second=mCalendar.get(Calendar.SECOND);
//繪製分針;
float degree=minute/60f*360;
canvas.save();
canvas.rotate(degree,width/2,height/2);
canvas.drawLine(width/2,height/2-200,width/2,height/2+20,mPaintMinute);
canvas.restore();
//繪製時針
float hourDegree=(hour*60+minute)/12f/60*360;
canvas.save();
canvas.rotate(hourDegree,width/2,height/2);
canvas.drawLine(width/2,height/2-150,width/2,height/2+20,mPaintHour);
canvas.restore();
//繪製秒針
canvas.save();//將當前矩陣和剪輯保存到私有堆棧上。
canvas.rotate(second*6,width/2,height/2);
canvas.drawLine(width/2,height/2-230,width/2,height/2+20,mPaintSecond);
canvas.restore();//用來去除所有修改最後一次調用保存的的矩陣/剪輯
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
繪製下載進度
圓形進度圖
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.administrator.canvas" >
<application
android:allowBackup="true"
android:icon="@mipmap/openofficeorg_draw"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
<Button
android:id="@+id/btn_download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="開始下載"/>
<com.example.administrator.canvas.widget.MyProgress
android:id="@+id/myprogress"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
MyProgress.java
public class MyProgress extends View{
private int width;
private int height;
private int currentProgress;
private Paint mPaintBackGround;
private Paint mPaintCurrent;
private Paint mPaintText;
private int maxProgress=100;
//得到進度的最大值
public int getMaxProgress() {
return maxProgress;
}
//設置進度的最大值
public void setMaxProgress(int maxProgress) {
this.maxProgress = maxProgress;
}
//得到當前的進度值
public int getCurrentProgress(){
return currentProgress;
}
//設置當前的進度值
public void setCurrentProgress(int currentProgress){
this.currentProgress=currentProgress;
invalidate();//刷新
}
public MyProgress(Context context) {
super(context);
}
public MyProgress(Context context, AttributeSet attrs) {
super(context, attrs);
mPaintBackGround=new Paint();
mPaintBackGround.setColor(Color.CYAN);
mPaintBackGround.setAntiAlias(true);//消除鋸齒
mPaintCurrent=new Paint();
mPaintCurrent.setColor(Color.GREEN);
mPaintCurrent.setAntiAlias(true);
mPaintText=new Paint();
mPaintText.setColor(Color.BLACK);
mPaintText.setTextSize(80);
mPaintText.setTextAlign(Paint.Align.CENTER);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width=getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
height=getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);
setMeasuredDimension(width,height);//設置畫布的大小,長和寬
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(width/2,height/8,100,mPaintBackGround);//設置背景的圖形
//設置當前下載進度的圖形
canvas.drawCircle(width/2,height/8,100f*currentProgress/maxProgress,mPaintCurrent);
//設置當前下載進度的文字顯示
canvas.drawText(currentProgress+"%",width/2,height/4,mPaintText);
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private MyProgress myProgress;
private static final int PORGRESS=0x23;
private Button btn_download;
private int progrress;
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch(msg.what){
case PORGRESS:
progrress++;
if (progrress<=100){
myProgress.setCurrentProgress(progrress);
handler.sendEmptyMessageDelayed(PORGRESS,20);
}
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myProgress= (MyProgress) findViewById(R.id.myprogress);
btn_download= (Button) findViewById(R.id.btn_download);
btn_download.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.sendEmptyMessageDelayed(PORGRESS,10);
}
});
}
}