Android 自定義View篇(二)Canvas詳解

圖片

做者:宋者爲王html

鏈接:https://cnblogs.com/andy-songwei/p/10960012.htmlcanvas

前言

上一篇講 View 的繪製流程中講到過,最後一步是 draw 流程,在這個過程當中,子 view 須要重寫 onDraw 方法來畫出本身的內容。在自定義 View 繪製自身內容的時候,系統提供了 3 個很是重要的類來幫助開發者畫各類炫酷的圖形:Canvas、Paint、Path。本篇主要介紹 Canvas 相關的內容,Paint 和 Path 在後面會單獨再作介紹。官方文檔中介紹的 Canvas 相關的 API 不少,本文主要介紹和梳理一些比較經常使用的實用功能。數組

本文的主要內容以下:app

圖片

1、一切的開始——onDraw

以下代碼展現了一個自定義 view 畫圖形的一個很是簡單的示例。這裏 onDraw 方法的參數 Canvas 就是本篇的主角了,中文意思「畫布」,意思就是全部「畫」的內容都是在這張畫布上完成的。ide

Paint paint = new Paint();
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 繪製一個原點座標(300,300),半徑爲200的圓
canvas.drawCircle(300300200, paint);
}

代碼很是簡單,可見自定義繪製上手很是容易。函數

2、Canvas 基本的 draw 功能

Canvas 包含了一些畫基本圖案的函數,基本都是以 drawXXX 的形式給出的。post

一、座標系

這裏先簡單介紹一下畫圖中所參照的座標系,是以當前 View 位置的左上角爲原點(0,0),水平方向向右爲 X 軸正方向,豎直向下爲 Y 軸正方向,這裏的 View 位置是個相對值,它取決於開發者把它放在哪裏。座標系大體以下所示,注意和平時咱們數學上座標系略有差異。spa

圖片

二、Paint

在 Canvas 的這些 drawXXX 方法中會用到 paint 類,它是畫筆,會決定繪製出來的圖形的顏色,是填充整個圖形仍是僅繪製邊框線條等多個屬性。這些會在之後專門介紹 Paint 的時候再講,這裏先提醒讀者注意,在筆者截取的效果圖中,我們這裏先只關注形狀,關於 piant,一概先用默認的填充。3d

三、drawColor()顏色填充

  1. 函數原型:drawColor(@color int color)。rest

  2. 做用:將整個繪製區域填充爲指定顏色(能夠設置透明度)。

  3. 示例:通常有三種方式來引用顏色值

//使用系統提供的顏色
canvas.drawColor(Color.BLACK);
//使用自定義顏色
canvas.drawColor(Color.parseColor("#000000"));
//使用color.xml中定義的顏色值
canvas.drawColor(getResources().getColor(R.color.black));
  1. 效果:
圖片
  1. 其它設置顏色的方法

    1)drawRGB(int r, int g, int b):根據 RGB 值來設置顏色

    2)drawARGB(int a, int r, int g, int b):根據透明度和 RGB 的值來設置顏色。

上述中的幾種方法,適用於在繪製前設置底色,或者在繪製完成後添加一層半透明蒙板。

四、drawCircle 畫圓

  1. 函數原型 drawCircle(float centerX, float centerY, float radius, Paint paint)。參數依次爲:X 座標,Y 座標,半徑,畫筆。

  2. 做用:以原點(centerX,centerY),半徑 radius,畫一個圓。

  3. 示例:

// 繪製一個原點座標(300,300),半徑爲200的圓
canvas.drawCircle(300300200, paint);
  1. 效果
image.png
  1. 五、drawRect 畫矩形
  1. 函數原型:drawRect(float left, float top, float right, float bottom, @NonNull Paint paint) 參數分別爲左邊、頂部、右邊、底部四條邊的座標值。

  2. 根據給定的 4 條邊框的座標,來畫矩形。

  3. 示例:

canvas.drawRect(100100500500, paint);
  1. 效果
image.png
  1. 其餘函數

    1) drawRect(@NonNull Rect r, @NonNull Paint paint)。實際上就是將前面函數定義爲一個 Rect 來做爲參數,做用和上面同樣。

    2)示例,效果和上述同樣。


canvas.drawRect(new Rect(100,100,500,500),mPaint);

六、drawPoint 畫點

  1. 函數原型:drawPoint(float x, float y, @NonNull Paint paint)。參數 x,y 分別爲該點的座標,點的大小和形狀由 paint 決定。

  2. 功能:在指定 x,y 座標處畫點

  3. 示例

canvas.drawPoint(5050, paint);
  1. 效果(和畫圓很相似,其實也能夠用來畫圓)
圖片

七、drawPoints 畫多個點

  1. drawPoints(float[] pts, int offset, int count,@NonNull Paint paint)。pts 這個數組是點的座標,每兩個成一對;offset 表示跳過數組的前幾個數再開始記座標;count 表示一共有多個數參與繪製。

  2. 示例:

float[] points = {005050501001005010010015050};
canvas.drawPoints(points, 2 /* 跳過兩個數,即前兩個 0 */,
8 /* 一共繪製 8 個數(4 個點)*/, paint);
  1. 效果。效果圖中 4 個點的座標分別爲(50,50)、(50,100)、(100,50)、(100,100)
圖片
  1. drawPoints( @NonNull float[] pts, @NonNull Paint paint);就是默認將上述函數的 offset 設置爲 0,count 設置爲全部數據參與繪製。

八、drawOval 畫橢圓

  1. 函數原型:drawOval(float left, float top, float right, float bottom, @NonNull Paint paint)。參數分別爲四個頂點所在切線座標。

  2. 做用:4 個參數肯定了一個矩形的 4 條邊框,這個矩形肯定了一個橢圓。該函數用於畫出這個指定的橢圓。

  3. 示例

canvas.drawOval(5050350200, paint);
  1. 效果
image.png
  1. 其它構造函數 :drawOval(RectF rect, Paint paint)

九、drawLine 畫直線

  1. 函數原型:drawLine(float startX, float startY, float stopX, float stopY, Paint paint)。參數值分別爲起始點座標和結束點座標。

  2. 做用:根據給定的起始點和結束點畫直線

  3. 示例

canvas.drawLine(200200800500, paint);
  1. 效果
image.png
  1. 批量畫線:drawLines(float[] pts, int offset, int count,Paint paint) / drawLines(float[] pts, Paint paint)。使用方法參照批量畫圓。

十一、drawArc 畫弧線或扇形

  1. 函數原型:drawArc(float left, float top, float right, float bottom, float startAngle,float sweepAngle, boolean useCenter, @NonNull Paint paint)。扇形或者弧線,都是橢圓(圓能夠當作是橢圓的特殊情形)上的一部分,因此畫扇形或者弧線須要先肯定好橢圓,前 4 個參數就是用於肯定這個橢圓。startAngle 表示起始角度,X 軸正方向(即水平向右方向)爲 0 度,順時針爲正角度,逆時針爲負角度。sweepAngle 表示弧線/扇形劃過的角度,依然是順時針爲正,逆時針爲負;useCenter 表示是否連到圓心,true 表示連到,表示扇形,false 表示不連到,表示弧線。

  2. 示例:

canvas.drawArc(200100800500, -110100true, paint); // 繪製扇型
canvas.drawArc(20010080050020140false, paint); // 繪製弧形
  1. 效果
圖片

十二、drawPath 畫自定圖形

  1. 函數原型:drawPath(Path path, Paint paint)

  2. 根據 path 定義的形狀來繪製。這個會在後續文章中詳細講。

1三、drawBitmap

  1. 函數原型:drawBitmap(Bitmap bitmap, float left, float top, Paint paint)。參數 bitmap 表示要繪製的圖片對象;left,top 表示要顯示的 bitmap 對象的左上角左邊位置。

  2. 做用:把指定的 bitmap 對象中的像素複製到指定位置。

  3. 示例:

Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.test);
canvas.drawBitmap(bitmap,100,50,paint);
  1. 效果
圖片
  1. 重載方法
drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint);
drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint);
drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint);

它們能夠指定複製原 bitmap 中的指定區域(Rect src 來肯定),到畫布中的指定位置(Rect dst)來肯定。

1四、drawText 繪製文字

函數原型:drawText(String text, float x, float y, Paint paint)。界面裏全部的顯示內容,都是繪製出來的,包括文字。drawText() 這個方法就是用來繪製文字的。參數 text 是用來繪製的字符串, x 和 y 是繪製的起點座標。文字的繪製在後面也會單獨詳細說明。

3、Canvas 實現裁剪

根據給定的範圍,對指定的 bitmap 進行裁剪,裁剪以後再進行繪製。範圍裁剪有兩個方法:clipRect()和 clipPath()。前者會截取一個矩形範圍,然後者 path 指定的形狀更多,因此裁剪的形狀也會更多。

1. Canvas.save()和 Canvas.restore()

在裁剪的過程當中,要加上這兩句代碼。它們用於保存和恢復繪製範圍,若是不加容易出現干擾。

2. clipRect()

canvas.save();
//目標bitmap
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.test);
//肯定須要裁剪的矩形範圍
canvas.clipRect(left, top, right, bottom);
//在指定的x,y座標開始繪製裁剪後的bitmap
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();

裁剪後的效果以下圖所示:

圖片

3. clipPath()

Canvas.clipRect(Path path) 用法徹底同樣,只是把參數換成了 Path ,因此能裁切的形狀更多一些。其對應有一個方法 Canvas.clipOutPaht(Path path),反向裁剪,效果能夠從截圖中看出來。

canvas.save();
canvas.clipPath(path1);
canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
canvas.restore();
canvas.save();
canvas.clipOutPath(path);
canvas.drawBitmap(bitmap, point2.x, point2.y, paint);
canvas.restore();
圖片

這個功能對顯示原型頭像比較有幫助。

4、Canvas 實現幾何變換

幾何變換的使用大概分爲三類:使用 Canvas 來作常見的二維變換;使用 Matrix 來作常見和不常見的二維變換;使用 Camera 來作三維變換。

一、使用 Canvas 來作常見的二維變換

  1. Canvas.translate(float dx, float dy) 平移。參數裏的 dx 和 dy 表示橫向和縱向的位移。

  2. Canvas.rotate(float degrees, float px, float py) 旋轉

  3. Canvas.scale(float sx, float sy, float px, float py)放大縮小

  4. Canvas.skew(float sx, float sy) 錯切,就是傾斜的意思。

canvas.save();
//水平向X軸正方向移動200px
canvas.translate(2000);
//以給定的點爲軸旋轉45度
canvas.rotate(45, centerX, centerY);
//以圖片中心爲軸,水平和豎直方向各放大爲原來的1.3倍
canvas.scale(1.3f1.3f, x + bitmapWidth / 2, y + bitmapHeight / 2);
canvas.skew(00.5f);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();

二、使用 Matrix 來作變換

使用 Matrix 能夠作常規的幾何變換,還能夠對圖形進行自定義變換。在作常規的幾何變換時,和前面介紹的用 Canvas 實現常規變換,功能同樣,選其一便可。

使用 Matrix 來作常規變換主要分三個步驟:

  • 建立Matrix對象;

  • Matrix.pre/postTranslate/Rotate/Scale/Skew()設置幾何變換;

  • Canvas.setMatrix(matrix)或Canvas.concat(matrix)把幾何變換應用到Canvas中(儘可能用後者)。

//1.建立Matrix對象
Matrix matrix = new Matrix();
matrix.reset();
//2.幾何變換
matrix.postTranslate(0,100);
matrix.postRotate(45,bitmap.getWidth()/2,bitmap.getHeight()/2);
matrix.postScale(1.3f,1.3f,x+bitmap.getWidth()/2,y+bitmap.getHeight()/2);
matrix.postSkew(0,0.5f);
canvas.save();
//3.把幾何變換應用到Canvas中
canvas.concat(matrix);
canvas.drawBitmap(bitmap,x,y,paint1);
canvas.restore();

圖片

Android 自定義View篇(一)View繪製流程

圖片

相關文章
相關標籤/搜索