1. 程式人生 > >自定義View之Canvas的使用

自定義View之Canvas的使用

Canvas是什麼?

Canvas顧名思義,就是畫布的意思.它在安卓中可以變換(旋轉,移動,縮放,錯切).在自定義View中,重寫onDraw時會傳入一個Canvas物件,我們可以用它來畫點(Point),線(Line),圓(Circle),文字(Text),圓弧(ARC),路徑(Path)等圖形.還可以暫時儲存畫布然後再次取出上次儲存的畫布進行操作.(畫布在不同的位置可以儲存,然後可以再次回到你想要回過去再繼續畫的地方,就可以省略計算把畫布移動到原來的位置).下面你就會知道了,不理解沒關係.

我們用Canvas來畫安卓中的2D圖形.通過巧妙的變換,能畫出一些很複雜的圖形.

Canvas怎麼用?

首先需要自定義一個View:

1.自定義類繼承View

2.重寫建構函式

3.重寫onDraw()方法

4.最後別忘了加到xml佈局檔案中

以下給出程式碼,至於下面測試部分,程式碼很多相同,只需修改onDraw函式中的內容即可

public class CanvasDemo extends View {
    private Paint mPaint;
    public CanvasDemo(Context context) {
        this(context,null);
    }

    public CanvasDemo(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CanvasDemo(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initControl();
    }

    private void initControl() {
        mPaint = new Paint();
//        抗鋸齒,就是讓圖形看上去沒有齒輪狀,看起來更柔和
        mPaint.setAntiAlias(true);
//        設定畫筆的風格
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.YELLOW);
//        設定畫筆的線帽
        mPaint.setStrokeCap(Paint.Cap.ROUND);
//        設定畫筆折斷處的樣式
        mPaint.setStrokeJoin(Paint.Join.ROUND);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
//        在此處修改下面的操作
    }
}

xml佈局檔案:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <xhj.zime.com.blogrect.CanvasDemo
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

這裡不討論畫筆的樣式(Style),線帽的樣式以及Join的樣式,下一篇文章介紹Paint的時候會具體介紹這些的作用以及用法,這裡我們只看Canvas相關的知識.

個人認為可以分為四個系列:

1.draw系列(畫)

2.clip系列(裁剪)

3.儲存與恢復系列

4.變換系列(錯切,旋轉,縮放,移動)

1.draw系列

通過api可以知道,drawXXX有很多,當然用法都是類似的,這裡演示主要的幾個,其他請物以類聚.

drawCircle:

        canvas.translate(getWidth() / 2, getHeight() / 2);
        canvas.drawCircle(0,0,100,mPaint);

畫圓,這裡我呼叫translate方法把畫布移到螢幕的中間,以便觀察所以做次變換.第一個引數為x軸移動距離,第二個引數為y軸移動距離

drawCircle中的引數含義:1.圓心x軸座標;2.圓心y軸座標;3.半徑;4.畫筆

drawLine:

        canvas.translate(getWidth() / 2, getHeight() / 2);
        mPaint.setStrokeWidth(30);
        canvas.drawLine(0,0,100,100,mPaint);

drawText:

        canvas.translate(getWidth() / 2, getHeight() / 2);
        mPaint.setTextSize(25);
        canvas.drawText("I am studying Android!",0,0,mPaint);

drawRect:

        canvas.translate(getWidth() / 2, getHeight() / 2);
        Rect rect = new Rect(0,0,200,200);
        canvas.drawRect(rect,mPaint);

如果想要精度大的,就用RectF即可

drawOval:

        RectF rectF = new RectF(0,0,100,200);
        canvas.drawOval(rectF,mPaint);

drawArc:useCenter為false

        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(5);
        RectF rectF = new RectF(0,0,100,200);
        canvas.drawArc(rectF,-180,270,false,mPaint);

這裡說一下,Paint的風格設定為STROKE是描邊的意思,不會填充他的內容,設定描邊的寬度

drawArc的引數含義:

1.需要一個矩形來畫圓弧

2.開始的角度

3.掃過的角度

4.是否使用中心點,不使用就不會和中心點相連,如果為true,就會和中心點相連,直接看效果就一目瞭然

5.畫筆物件

drawArc:(useCenter為true)

        canvas.translate(getWidth() / 2, getHeight() / 2);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(5);
        RectF rectF = new RectF(0,0,100,200);
        canvas.drawArc(rectF,-180,270,true,mPaint);

drawPath:

        canvas.translate(getWidth() / 2, getHeight() / 2);
        Path path = new Path();
        path.moveTo(-50,-50);
        path.lineTo(50,50);
        path.lineTo(200,50);
        path.lineTo(300,10);
        canvas.drawPath(path,mPaint);

Path類,這裡不是檔案的路徑類,而是單純的路徑類,moveTo方法表示將這個原點移動到某一個位置,然後用lineTo連線每一個點,如果最後沒有連線到原點,會自動連線到原點去.

有一個rMoveTo和rLineTo方法,表示的是相對移動,沒有就是絕對的,相對指的不是座標,而是相對上一個座標移動多少,而不是移動到哪個座標.

還有其他類似的draw方法,自行閱讀api文件解決,其實都差不多.drawTextOnPath只不過是沿著路徑寫字,java的命名我相信已經寫的非常清楚了.

2.clip系列

未完待續.....