前言
我們都知道,現實生活中畫一幅畫需要筆和紙,另外還需要各式各樣的繪畫技巧,那麼同樣的自定義view也需要這些。正好Android也給我們提供了這兩樣東西:Paint和Canvas,一個是畫筆而另一個呢當然是畫布啦
Paint中有各種setter方法可以設置不同的屬性,比如setColor()設置畫筆顏色,setStrokeWidth()設置描邊線條,setStyle()設置畫筆的樣式:
![]()
Paint集成了所有“畫”的屬性,而Canvas則定義了所有要畫的東西,我們可以通過Canvas下的各類drawXXX方法繪製各種不同的東西,比如繪製一個圓drawCircle(),繪製一個圓弧drawArc(),繪製一張位圖drawBitmap()等等等:
初步瞭解完這些,就可以嘗試繪製一個view了
具體步驟如下
首先新建一個AndroidStudio項目CustomView,然後在項目中新建一個views的包用於寫自定義view相關的類,這裏我們在views的包裏新建一個CustomView類讓它繼承View類實現Runnable接口,具體代碼如下所示:
package com.lijizhi.customviewdemo.views;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/* 項目名 CustomViewDemo
* 包名 com.lijizhi.customviewdemo.views
* 文件名: CustomView
* 創建者 : LJZ
* 創建時間:2017/10/13 0013 上午 7:41
* 描述 自定義View
*/
public class CustomView extends View implements Runnable{
private Paint mPaint; //畫筆
private Context mContext;//上下文的引用
private int radiu;//圓環半徑
public CustomView(Context context){
this(context,null);
}
public CustomView(Context context, AttributeSet attrs){
super(context,attrs);
mContext=context;
initPaint();//初始化畫筆
}
private void initPaint() {
//實例化畫筆,並打開抗鋸齒
mPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
/*
* 設置畫筆樣式爲描邊,圓環嘛……當然不能填充不然就麼意思了
*
* 畫筆樣式分三種:
* 1.Paint.Style.STROKE:描邊
* 2.Paint.Style.FILL_AND_STROKE:描邊並填充
* 3.Paint.Style.FILL:填充
*/
mPaint.setStyle(Paint.Style.STROKE);
//設置畫筆顏色爲淺灰色
mPaint.setColor(Color.LTGRAY);
/*
* 設置描邊的粗細,單位:像素px
* 注意:當setStrokeWidth(0)的時候描邊寬度並不爲0而是隻佔一個像素
*/
mPaint.setStrokeWidth(10);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
//繪製圓環
canvas.drawCircle(MeasureUtil.getScreenSize((Activity) mContext)[0] / 2, MeasureUtil.getScreenSize((Activity) mContext)[1] / 2, radiu, mPaint);
}
@Override
public void run(){
//確保線程不斷執行不斷刷新頁面
while(true){
try{
//如果半徑小於200則自加,否則大於200後重置半徑值以實現往復
if(radiu<200){
radiu+=10;
// 刷新View
postInvalidate();
}else{
radiu=0;
}
//每執行一次暫停40毫秒
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
簡單分析一下以上的代碼,首先在CustomView類中聲明瞭三個屬性,分別爲mPaint(畫筆),mContext(上下文),radiu(圓環半徑),緊接着就是編寫CustomView的構造方法及重載方法,這裏不得不提的是重載方法的第二個參數AttributeSet,爲什麼需要這個參數呢?因爲我們定義一個view會用到layout_width,layout_height等等這些屬性,所以就必須傳入這個參數,否則會報錯。然後就是實例化畫筆對象,在onDraw方法裏編寫相應的邏輯操作,這裏要想讓圓環有動畫效果,則必須開啓一個子線程不斷更改圓環的半徑並刷新頁面。
在繪製圓環的寬高這一塊,我們用到了 MeasureUtil.getScreenSize,這裏的工具類及其方法是需要我們自己定義的,具體代碼如下所示:
package com.lijizhi.customviewdemo.views;
import android.app.Activity;
import android.util.DisplayMetrics;
/* 項目名 CustomViewDemo
* 包名 com.lijizhi.customviewdemo.views
* 文件名: MeasureUtil
* 創建者 : LJZ
* 創建時間:2017/10/13 0013 上午 7:41
* 描述 繪製工具類
*/
public final class MeasureUtil {
/**
* 獲取屏幕尺寸
*
* @param activity
*
* @return 屏幕尺寸像素值,下標爲0的值爲寬,下標爲1的值爲高
*/
public static int[] getScreenSize(Activity activity){
DisplayMetrics metrics=new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
return new int[]{metrics.widthPixels,metrics.heightPixels};
}
}
做完了前兩步,我們就要在佈局文件中引入我們剛剛自定義的view
如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical" >
<com.lijizhi.customviewdemo.views.CustomView
android:id="@+id/main_cv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
最後一步我們只需要在MainActivity中獲取控件並開啓子線程就行了。
package com.lijizhi.customviewdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.lijizhi.customviewdemo.views.CustomView;
public class MainActivity extends AppCompatActivity {
private CustomView mCustomView; //我們自定義View
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
// 獲取控件
mCustomView=(CustomView)findViewById(R.id.main_cv);
/*
* 開線程
*/
new Thread(mCustomView).start();
}
}
最終效果如下圖
這裏我就簡單的截了個圖,實際的動態效果,大家可以自己跟着做一遍就好了。