1. 程式人生 > >Android高階進階——繪圖篇(一)Canvas基本操作

Android高階進階——繪圖篇(一)Canvas基本操作

開篇

前面在介紹 onDraw 過程時,有提到 View 的繪製(Canvas 的使用),後續的幾篇會詳細的介紹有關 Canvas 以及 Paint 的相關操作。

Canvas 和 Paint

Canvas 和 Paint 之間的關係就像我們平時畫畫需要的畫筆和畫紙一樣,我們畫畫無外乎也就需要這兩個工具,而這兩個工具體現在 Android 中,就是我們的 Paint(畫筆)和 Canvas(畫紙,通常稱為畫布),所以凡是跟要畫的東西設定相關的,比如顏色、大小、寬度、樣式、透明度等都是在 Paint 中設定的。而凡是跟要畫的成品,比如想畫一個矩形、圓形、文字、路徑等都是通過 Canvas 操作的。

Canvas 的基本操作

  • 新建一個類,派生自 View,重寫 View 的 onDraw 方法,在 onDraw 方法中通過 Canvas 來實現我們想要實現的效果:
public class CustomView extends View {

    private Paint paint;

    public CustomView(Context context) {
        super(context);
        init();
    }

    private void init() {
        //初始化畫筆
        paint = new
Paint(); //設定抗鋸齒 paint.setAntiAlias(true); //設定畫筆寬度 paint.setStrokeWidth(5); //設定畫筆顏色 paint.setColor(Color.RED); //設定畫筆樣式 paint.setStyle(Paint.Style.STROKE); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } }
  • 然後在佈局檔案中使用我們的自定義View:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android”
    xmlns:app="http://schemas.android.com/apk/res-autoxmlns:tools="http://schemas.android.com/tools”
    android:layout_width=“match_parent”
    android:layout_height=“match_parent”
    android:orientation=“vertical”
    tools:context=“com.example.hecom.annotationlibrary.MainActivity”>

    <com.example.hecom.annotationlibrary.CustomView
        android:layout_width=“match_parent”
        android:layout_height="match_parent” />

</LinearLayout>
  • 畫就行了

1、使用 Canvas 畫圓

void drawCircle (float cx, float cy, float radius, Paint paint)

引數:
- cx:圓心點的 X 軸座標
- cy:圓心點的 Y 軸座標
- radius:圓的半徑
- paint:畫筆

   private void init() {
        //初始化畫筆
        paint = new Paint();
        //設定抗鋸齒
        paint.setAntiAlias(true);
        //設定畫筆寬度
        paint.setStrokeWidth(5);
        //設定畫筆顏色
        paint.setColor(Color.RED);
        //設定畫筆樣式
        paint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(300,300,100,paint);

    }

image.png

2、使用 Canvas 畫矩形

void drawRect (float left, float top, float right, float bottom, Paint paint)
void drawRect (RectF rect, Paint paint)
void drawRect (Rect r, Paint paint)

引數:

  • 第一種寫法是直接傳入矩形的四個點的位置,畫出矩形
  • 第二種寫法是根據傳入的 RectF 以及 Rect 矩形變數來指定所畫的矩形
  • 矩形工具類 RectF 與 Rect
    這兩個都是矩形輔助類,區別不大,用哪個都可以,根據四個點構建一個矩形結構,在畫圖時,利用這個矩形結構可以畫出對應的矩形或者與其他圖形 Region 相交、相加等
  • RectF
    建構函式有四個,但最常用的還是第二個,根據四個點構造出一個矩形
    RectF()
    RectF(float left, float top, float right, float bottom)
    RectF(RectF r)
    RectF(Rect r)
  • Rect
    建構函式有三個,最常用的也是根據的四個點來構造矩形
    Rect()
    Rect(int left, int top, int right, int bottom)
    Rect(Rect r)
        canvas.drawRect(100, 100, 300, 300, paint);
        canvas.drawRect(new Rect(400, 100, 600, 300), paint);
        canvas.drawRect(new RectF(100, 400, 300, 600), paint);

效果圖:
image.png

3、使用 Canvas 繪製圓角矩形

void drawRoundRect (RectF rect, float rx, float ry, Paint paint)
void drawRoundRect (float left, float top, float right, float bottom, float rx, float ry, Paint paint)

引數:
- rect:要畫的矩形
- rx:生成圓角的橢圓的 X 軸半徑
- ry:生成圓角的橢圓的 Y 軸半徑

onDraw 中程式碼實現:

        canvas.drawRoundRect(100, 100, 300, 300, 50, 50,paint);
        canvas.drawRoundRect(new RectF(100, 400, 300, 600), 50, 50,paint);

image.png

4、使用 Canvas 繪製橢圓

橢圓是根據矩形生成的,以矩形的長為橢圓的 X 軸,矩形的寬為橢圓的 Y 軸,建立的橢圓圖形

void drawOval (RectF oval, Paint paint)

引數:
- RectF oval:用來生成橢圓的矩形

onDraw 方法

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(100, 400, 700, 700, paint);
        paint.setColor(Color.BLUE);
        canvas.drawOval(new RectF(100, 400, 700, 700), paint);
    }

效果圖:
image.png

5、使用 Canvas 繪製圓弧

弧是橢圓的一部分,而橢圓是根據矩形來生成的,所以弧當然也是根據矩形來生成的。

void drawArc (RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

引數:
- RectF oval:生成圓弧的矩形
- float startAngle :圓弧開始的角度,以 X 軸正方向為 0 度
- float sweepAngle:圓弧持續的角度
- boolean useCenter:是否顯示弧的兩邊,true,顯示,false 不顯示,只有一條弧線

onDraw 方法:

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //0 - 90 度,不顯示弧邊
        canvas.drawRect(100, 300, 400, 500, paint);
        paint.setColor(Color.BLUE);
        canvas.drawArc(new RectF(100, 300, 400, 500), 0, 90, false, paint);

        //0 - 90 度,顯示弧兩邊
        paint.setColor(Color.RED);
        canvas.drawRect(100, 600, 400, 800, paint);
        paint.setColor(Color.BLUE);
        canvas.drawArc(new RectF(100, 600, 400, 800), 0, 90, true, paint);

        //-90 - 90 度,不顯示弧兩邊
        paint.setColor(Color.RED);
        canvas.drawRect(100, 900, 400, 1100, paint);
        paint.setColor(Color.BLUE);
        canvas.drawArc(new RectF(100, 900, 400, 1100), -90, 180, false, paint);

        //-90 - 90 度,顯示弧兩邊
        paint.setColor(Color.RED);
        canvas.drawRect(100, 1200, 400, 1400, paint);
        paint.setColor(Color.BLUE);
        canvas.drawArc(new RectF(100, 1200, 400, 1400), -90, 180, true, paint);


        //0 - 360 度,顯示弧兩邊
        paint.setColor(Color.RED);
        canvas.drawRect(500, 700, 800, 900, paint);
        paint.setColor(Color.BLUE);
        canvas.drawArc(new RectF(500, 700, 800, 900), 0, 360, true, paint);
    }

效果圖:
image.png

6、使用 Canvas 畫直線

void drawLine (float startX, float startY, float stopX, float stopY, Paint paint)

引數:
- float startX:開始點 X 座標
- float startY:開始點 Y 座標
- float stopX:結束點 X 座標
- float stopY:結束點 Y 座標

onDraw 方法:

    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawLine(100, 100, 500, 900, paint);
        paint.setStrokeWidth(50);
        canvas.drawLine(200, 100, 600, 900, paint);


    }

效果圖:
image.png

7、使用 Canvas 畫多條直線

void drawLines (float[] pts, Paint paint)
void drawLines (float[] pts, int offset, int count, Paint paint)

引數:
- float[] pts:pts 是點的集合,每兩個點形成一條連線線,100, 100, 500, 900 這四個數字其實就是確定了要連線的兩個點的位置

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

        float[] pts = {100, 100, 200, 200, 300, 300, 500, 500};

        canvas.drawLines(pts, paint);


    }

效果圖:
image.png

暫時先介紹這麼多,關於 drawText 以及 drawPath ,這兩個東西牽扯比較多,稍後會單獨開兩篇介紹。