1. 程式人生 > >Android中Paint和Canvas的簡單使用

Android中Paint和Canvas的簡單使用

在 Android 中,Canvas 相當於畫布,而 Paint 相當於畫筆;那麼這兩個配合使用就可以畫出來我們想要的形狀了。

首先我們新建一個類,名字叫 MyView,重寫 onDraw() 方法,程式碼如下:

@SuppressLint("AppCompatCustomView")
public class MyView1 extends View {
    private Paint mPaint;

    public MyView1(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
    }
}

1. 畫點

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /**
         * 畫一個點;drawPoint引數為:點的x座標、點的y座標、畫筆
         */
        mPaint.setColor(Color.RED);
        //設定畫筆寬度
        mPaint.setStrokeWidth(50);
        canvas.drawPoint(100,100,mPaint); 
    }

在程式碼中新增上面的程式碼,一個點就畫出來了,下面是效果圖:

當然,也可以連續的畫多個點,程式碼如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 多個點,pts中引數為:
         * 第一個點的x座標、第一個點的y座標;
         * 第二個點的x座標、第二個點的y座標;
         * 第三個點的x座標、第三個點的y座標;
         */
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(50);
        float[] pts = {100,100,200,200,300,300};
        canvas.drawPoints(pts,mPaint);
    }

效果圖如下:

連續的畫多個點還有一個方法,具體看下面程式碼:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 多個點,drawPoints引數為:
         * 1.要繪製的點陣列[x0 y0 x1 y1 x2 y2…]。
         * 2.開始繪製前要跳過的值的個數。下面的offset=2:跳過前兩個座標,從第三個座標開始畫,即從第二個點開始畫
         * 3.跳過個數後,要處理的值的個數。下面的count=8:跳過前兩個座標,繼續畫8個座標,即再畫4個點
         */
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(50);
        float[] pts = {100,100,200,200,300,300,400,400,500,500,600,600};
        canvas.drawPoints(pts,2,8,mPaint);
    }

效果圖如下:

2. 畫線

確定兩點位置既可以畫出一條線,程式碼也很簡單:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 畫一條線
         * 引數為:
         * 第一個引數:x開始座標
         * 第二個引數:y開始座標
         * 第三個引數:x結束座標
         * 第四個引數:y解釋座標
         * 第五個引數:畫筆
         */
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(5);
        canvas.drawLine(10,10,200,200,mPaint);
    }

效果圖如下:

3. 畫三角形

三角形即是確定三個點座標,便可以畫出一個三角形了,程式碼如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 畫三角形
         * 一共12個座標,引數分別為:
         * 1-4:第一條線的起始x,y座標和結束x,y座標
         * 5-8:第二條線的起始x,y座標和結束x,y座標
         * 9-12:第三條線的起始x,y座標和結束x,y座標
         */
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(5);
        float[] pts = {400,400,700,700,400,400,100,700,100,700,700,700};
        canvas.drawLines(pts,mPaint);
    }

效果圖如下:

4. 畫矩形

確定三個點座標可以畫出三角形,那麼確定四個點的座標也可以畫出一個矩形;這裡給出另一個畫矩形的方法,確定第一個點 (左上角) 的座標和第四個點 (右下角) 的座標也可以滑出一個矩形,看下面的程式碼:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 畫矩形,單位是畫素,引數為:
         * 前兩個:第一個點的座標;後兩個:第四個點的座標
         */
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(5);
        canvas.drawRect(0,0,200,400,mPaint);
    }

效果圖如下:

可以看出,這個是個實心的,和上面一條線一條線畫出來的不怎麼一樣,其實改變一個引數即可,如下面程式碼:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 畫矩形另一種方式
         * 三種風格為:
         * Style.STROKE:只描邊
         * Style.FILL:填充
         * Style.FILL_AND_STROKE:填充並描邊
         * Rect中四個引數:前兩個:第一個點的座標;後兩個:第四個點的座標
         */
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);
        Rect rect = new Rect(100,100,300,300);
        canvas.drawRect(rect, mPaint);
    }

可以看出只需要設定 Style 即可了,下面是效果圖:

5. 畫圓角矩形

矩形畫完,就看一下如何畫圓角矩形,也是很簡單,看程式碼:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 圓角矩形
         * drawRoundRect中引數為:
         * 第一個和第二個:第一個點座標
         * 第三個和第四個:第四個點座標
         * 第五個和第六個:x、y軸上的圓角大小
         */
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawRoundRect(100, 100, 200, 200, 20, 20, mPaint);
    }

效果圖如下:

6. 畫圓形

畫一個圓只需要確定中點的座標和半徑大小就可以畫出來了,程式碼如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 畫圓形,引數為:
         *前兩個:中心點的座標;第三個:半徑大小
         */
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(5);
        canvas.drawCircle(200,100,50,mPaint);
    }

下面是效果圖:

7. 畫橢圓

橢圓是矩形的內切圓,也就是畫橢圓之前要先畫出矩形,然後再畫出橢圓,程式碼如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 畫橢圓1
         * 先畫一個矩形,再在矩形中畫橢圓
         * RectF中引數為:前兩個是矩形第一個點的座標;後兩個是矩形最後一個點的座標
         */
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);
        RectF rectF = new RectF(100,100,500,400);
        canvas.drawRect(rectF,mPaint);
        mPaint.setColor(Color.BLACK);
        canvas.drawOval(rectF,mPaint);
    }

效果圖如下:

這裡要注意的是:只需要給出矩形的第一個點座標和第四個點座標就可以畫出橢圓了,和畫矩形十分相似;

下面再來看一個例子:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 畫橢圓2
         * 橢圓是根據一個矩形的內切圓而定的,
         * 所以也可以直接給出矩形的第一個點座標和最後一個點座標,直接畫出橢圓,
         * 隱藏了矩形,直接顯示了橢圓
         */
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawOval(100, 100, 600, 300, mPaint);
    }

效果圖如下:

8. 畫弧

弧是橢圓來定的,橢圓是根據矩形而定的,那麼弧和矩形也脫不了干係:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 畫弧
         * drawArc中引數:
         * startAngle :圓弧開始的起始角(度)
         * sweepAngle :順時針測量掃掠角(度)即:90度為1/4個橢圓;180為1/2個橢圓
         * useCenter :false,只顯示一段弧;否則顯示線段和弧
         */
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);
        RectF rectF = new RectF(100,100,600,300);
        canvas.drawArc(rectF,0,90,true,mPaint);
    }

下面是效果圖:

上面有個引數 useCenter 改為 true 是上面的效果;來看一下改為 false 的效果圖:

可以看到少了兩條線,對畫弧有一定了解後,來看一下弧的來歷:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 畫弧2:弧的來歷
         * drawArc中引數:
         * startAngle :圓弧開始的起始角(度)
         * sweepAngle :順時針測量掃掠角(度)即:90度為1/4個橢圓;180為1/2個橢圓
         * useCenter :false,只顯示一段弧;否則顯示線段和弧
         */
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);
        RectF rectF = new RectF(100,100,600,300);
        //先畫一個矩形
        canvas.drawRect(rectF,mPaint);
        //再畫一個橢圓
        mPaint.setColor(Color.BLACK);
        canvas.drawOval(rectF,mPaint);
        //最後畫弧
        mPaint.setColor(Color.BLUE);
        canvas.drawArc(rectF,0,90,true,mPaint);
    }

 可以看出,首先畫出一個矩形,其次畫出一個橢圓,最後得到了一段弧,下面是效果圖:

可以清楚看出來了,不懂的來看下面圖片的分析,這是數學的東西,弧度什麼的我就不再多說了:

看懂之後,最後再看一個關於弧度的小例子:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 畫弧3
         * drawArc中引數:
         * startAngle :圓弧開始的起始角(度)
         * sweepAngle :順時針測量掃掠角(度)即:90度為1/4個橢圓;180為1/2個橢圓
         * useCenter :false,只顯示一段弧;否則顯示線段和弧
         */
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);
        RectF rectF = new RectF(100,100,600,300);
        canvas.drawArc(rectF,90,-180,true,mPaint);
    }

效果圖如下:

9. 畫多邊形

基本的都瞭解完,來看一下自定義多邊形:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 多邊形1
         * moveTo():第一個點座標
         * lineTo():第二個點座標,第三個點座標等;後面所有點座標都寫在裡面
         * close():寫完點之後呼叫;它讓此多邊形保持閉合狀態
         */
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);
        Path path = new Path();
        path.moveTo(100,100);
        path.lineTo(100,500);
        path.lineTo(300,500);
        path.lineTo(600,200);
        path.close();
        canvas.drawPath(path,mPaint);
    }

下面是效果圖:

很醜的多邊形出現了;我來在多邊形上又加圖形,修改程式碼為:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 多邊形2
         * Direction方法:指定新增到路徑時封閉形狀(例如矩形、橢圓)的方向。
         * Direction方法中有兩個引數:
         * CW:即clockwise,順時針方向
         * CCW:即counter-clockwise,逆時針方向
         */
        mPaint.setColor(Color.BLACK);
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);
        Path path = new Path();
        path.moveTo(100, 100);
        path.lineTo(100, 500);
        path.lineTo(300, 500);
        path.lineTo(600, 200);
        path.close();
        //多邊形中新增一個圓
        path.addCircle(100,100,30,Path.Direction.CW);
        //多邊形中新增一個矩形
        path.addRect(100,300,200,500,Path.Direction.CCW);
        //多邊形中新增一個弧
        path.addArc(0,400,200,600,0,-90);
        canvas.drawPath(path, mPaint);
    }

效果圖如下:

很奇怪的圖形出現了,大家可以自己多寫點作為練習,加深理解;

10. 圖片中新增文字

圖形畫的差不多了,下面來在上面新增一些文字:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 形狀內新增文字
         * drawTextOnPath內的引數為:
         * 1.要繪製的文字
         * 2.文字應遵循的基線路徑,即建立的圖形
         * 3.沿路徑新增到文字起始位置的距離;即距離x軸的距離
         * 4.文字定位路徑上(-)或下(+)的距離;越大越偏離圖形
         * 5.畫筆
         */
        mPaint.setColor(Color.BLUE);
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);
        String text = "Hello, everybody!I am wuqingsen";
        Path path = new Path();
        path.addCircle(400, 400, 200, Path.Direction.CCW);
        canvas.drawPath(path, mPaint);
        mPaint.setTextSize(60);
        mPaint.setColor(Color.BLACK);
        //設定抗鋸齒
        mPaint.setAntiAlias(true);
        canvas.drawTextOnPath(text, path, 0, 0, mPaint);
    }

下面是效果圖:

密密麻麻,醜了吧唧;上面 drawTextOnPath 方法中的第三個和第四個引數是什麼意思呢,我將兩個值便大後,程式碼如下:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas); 
        /**
         * 文字2
         */
        mPaint.setColor(Color.BLUE);
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);
        String text = "Hello, everybody!I am wuqingsen";
        Path path = new Path();
        path.addCircle(400, 400, 200, Path.Direction.CCW);
        canvas.drawPath(path, mPaint);
        mPaint.setTextSize(60);
        mPaint.setColor(Color.BLACK);
        //設定抗鋸齒
        mPaint.setAntiAlias(true);
        canvas.drawTextOnPath(text, path, 100, 60, mPaint);
    }

效果圖如下:

這樣對這兩個引數應該也有所瞭解。我將 CCW 改為 CW ;效果圖如下:

可以看出方向變為了順時針。

Android 中 Paint 和 Canvas 的簡單使用就到這裡了。

有興趣的可以點這裡:塗鴉功能的簡單實現