1. 程式人生 > >Android Canvas API使用

Android Canvas API使用

這裡記錄一下Canvas 相關API的使用,權當自己作筆記,以後需要好參考

前面有一文Android應用程式視窗View的draw過程講到View的繪製過程,其中說到,View繪製自己的內容是在它的onDraw()回撥裡進行的,這個回撥帶有一個引數,引數型別就是Canvas,View的內容繪製需要用到Canvas。

關於Canvas,官方文件:https://developer.android.com/reference/android/graphics/Canvas.html

Canvas有許多以draw開頭的函式:



如上所示,根據這些函式的名字可以大概知道這些函式的作用。就是繪製各種圖形,例如填充色,文字,圓,線....這些豐富的API為支援我們自定義內容豐富的View,因為android提供的控制元件畢竟有限,在有些情況,還是需要自定義View,自定義View無非就是UI個性化設定,這個時候過載onDraw()函式,然後在這個回撥裡,利用Canvas的API繪製自己想要的內容。

看看上Canvas的draw相關函式,可以發現,還有一個物件經常作為引數傳入,就是Paint,就翻譯為畫筆,可以這麼理解Canvas只是一塊布,而在該布上執行繪製的操作(畫線,畫圓)都是由Paint完成的,所以這個Paint很重要。下面就簡單看一下Canvas的相關函式:

首先看一下設定Canvas的填充色:

canvas.drawColor(Color.BLUE);
        
   canvas.drawARGB(255,255,0,0);

上面兩個函式都可以設定畫布的填充色

下面的draw函式都需要用到Paint,先看一下Paint:

https://developer.android.com/reference/android/graphics/Paint.html

Paint類常用方法:

setARGB(int a, int r, int g, int b) // 設定 Paint物件顏色,引數一為alpha透明值

setAlpha(int a) // 設定alpha不透明度,範圍為0~255

setAntiAlias(boolean aa) // 是否抗鋸齒

setColor(int color)  // 設定顏色,這裡Android內部定義的有Color類包含了一些常見顏色定義

setTextScaleX(float scaleX)  // 設定文字縮放倍數,1.0f為原始

setTextSize(float textSize)  // 設定字型大小

setUnderlineText(booleanunderlineText)  // 設定下劃線

demo的佈局檔案:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="cj.com.canvasdemo.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
    <cj.com.canvasdemo.MyView
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

看一下MyView:
package cj.com.canvasdemo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

/**
 * 
 */

public class MyView extends View {
    Paint paint;
    public MyView(Context context) {
        super(context);
    }

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint(); //
        paint.setColor(Color.RED);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setStrokeWidth(3);
    }

    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //...自定義繪製
    }
}
這裡畫筆預設的style是填充的,所以下面效果都是填充的效果。

1。繪製弧形:


先看第一個函式,這個函式API 21 才新增的

canvas.drawArc(20,20,300,300,0,90,true,paint);
效果:

前面四個引數圍成的矩形,在矩形內繪製內切弧形,第5,6個引數分別是起始角度,和結束角度,是按順時針來繪製的,第7個布林型引數表示是否繪製中心那一塊,看一下為false的情況:

差別很明顯,最後一個引數就是Paint。

第二函式比第一個函式也就是少了三個引數,其實是把第一個函式的前面的四個引數,封裝到RectF這個物件了,這個物件代表就是矩形:

 RectF rectF = new RectF(20,20,300,300);
        canvas.drawArc(rectF,0,90,false,paint);

效果和上面一樣。

2.繪製圓:

canvas.drawCircle(200,200,100,paint);

這個函式比較好理解,第1,2個引數就是圓心位置的x,y座標。第3個圓的半徑,第四個paint

3.繪製線:


首先看第一個函式

canvas.drawLine(50,60,120,140,paint);


這個函式也比較好理解,繪製直線肯定需要兩個端點,前面四個引數就是兩個端點x,y座標

看第二個函式,稍微複雜點:

 float[] ps = {20,30,150,180,50,40,90,100,50,60};
        canvas.drawLines(ps,0,8,paint);


它的作用繪製很多條直線,這些直線的端點的x,y座標就通過一個浮點陣列來表示,每個四個值代表兩個端點。

第一個引數就是陣列,第二個引數是偏移位置,就是從陣列第幾個位置開始取值開始繪製直線,我這裡是0,表示20作為第一個端點的x座標,如果偏移位置是2的話表示捨棄前面的20,30,取150作為第一條直線的第一個端點的x座標。第三個引數表示取陣列中幾個值來繪製直線,如果想繪製直線的至少要4個值,當然要是4的倍數才會繪製相應的直線。比如你傳3那麼就不能繪製一條直線,如果傳入4到7之間的值,也只能繪製一條直線。當然你也要根據陣列的值的個數來設定,超過陣列的大小會報異常的,第4個引數就是paint。
看第三個函式:

float[] ps = {20,30,150,180,180,40,90,100,50,60,70,130};
        canvas.drawLines(ps,paint);
這個函式和第二函式相似,都是用來繪製一系列直線,用陣列來儲存直線端點的x,y座標值。不過這個函式比較智慧,它以陣列的大小來判斷繪製多少條直線,直接繪製出來。


4.繪製橢圓


繪製橢圓和繪製弧形差不多

首先看第一個函式,這個函式也是API LEVEL 21才新增的

canvas.drawOval(20,80,500,500,paint);

函式的前面四個引數圍成矩形,在矩形內繪製內切橢圓

第二個函式,就是將第一個函式的前面四個引數封裝成RectF物件。

 RectF rectF = new RectF(20,80,500,500);
        canvas.drawOval(rectF,paint);
效果一樣。

5.繪製path

path可翻譯為路徑,https://developer.android.com/reference/android/graphics/Path.html

Path類功能很強大,主要用於繪製複雜的圖形輪廓,關於Path的簡紹該文就不作詳說了,大家可以查閱資料

 Path path = new Path(); //定義一條路徑
        path.moveTo(60, 60); //起始點 座標60,60
        path.lineTo(100, 100);//連線直線
        path.lineTo(200,80);
        path.lineTo(60, 60);
        canvas.drawPath(path,paint);


6,繪製點


繪製點就比較簡單了,這三個函式也不難理解,跟繪製直線那三個函式差不多

 float[] ps = {20,30,150,180,180,40,90,100,50,60,70,130};
      canvas.drawPoints(ps,paint);

這個就不細說了

7.繪製矩形和圓角矩形



這個也比較好理解

  //Rect rect = new Rect(20,20,300,300);
        RectF rectF = new RectF(20,20,300,300);
        canvas.drawRect(rectF,paint);

Rect和RectF就是傳入的座標值為整數和浮點型的差別

RectF rectF = new RectF(20,20,300,300);
        canvas.drawRoundRect(rectF,50,50,paint);

第2,3個引數表示x,y方向上弧度。


8.繪製文字:


繪製文字的函式較多,但是常用就那麼一兩個,其他就不分析了

canvas.drawText("Android",60,60,paint);

9.繪製圖片


繪製bitmap的函式也較多,不細說了

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
        canvas.drawBitmap(bitmap,70,70,paint);

以上是Canvas能夠繪製的各種內容,還有一些沒有講到。

我們自定義View可能不單單隻繪製一種圖形,而是多種圖形一起繪製。

而且在繪製圖形的時候,還要考慮畫布位置的變換(translate(float dx, float dy))和畫布的儲存與恢復(save()、restore())

關於canvas的變換,參考http://blog.csdn.net/harvic880925/article/details/39080931

本文就介紹這麼點