最近在跟扔物線大嬸學(xué)自定義控件,其實許多東西之前都用過的,不過時間長就忘了,然后這次就系統(tǒng)的復(fù)習(xí)一下,順便記錄下來。
自定義繪制,首先要創(chuàng)建好Paint對象,重寫onDraw(),把繪制代碼寫在onDraw()里,這就是自定義繪制最基本的實現(xiàn)。Paint和canvas組合使用可以畫出各種各樣的圖形。
Paint類的常用方法
- paint.setStyle(Style style) 設(shè)置繪制模式
- paint.setColor(int color) 設(shè)置顏色
- paint.setStrokeWidth(float width) 設(shè)置線條寬度
- paint.setTextSize(float textSize) 設(shè)置文字大小
- paint.setAntiAlias(boolean aa) 設(shè)置抗鋸齒開關(guān)(初始化Paint時可直接設(shè)置)
paint.setStyle(Style style)主要有三種樣式:FILL,STROKE和FILL_AND_STROKE。FILL 是填充模式,STROKE 是畫線模式(即勾邊模式),F(xiàn)ILL_AND_STROKE 是兩種模式一并使用:既畫線又填充。它的默認值是 FILL,填充模式。
1.canvas.drawColor()顏色填充
這算是最簡單的了,直接canvas.drawColor(Color.Yellow)。類似的方法還有drawColor(Color.parse("")),直接填16進制色值就行,例如drawColor(Color.parse("#F00")),drawColor(Color.parse("#6F00")),drawColor(Color.parse("#CCCCCC")),drawColor(Color.parse("#88880000"))。 drawRGB(int r, int g, int b),drawARGB(int a, int r, int g, int b)
canvas.drawColor(Color.YELLOW);
2.canvas.drawCircle(float centerX, float centerY, float radius, Paint paint)畫圓
前兩個參數(shù)表示圓的圓心坐標,radius是圓心半徑,paint可以設(shè)置圓的填充顏色,空心圓還是實心圓還是圓環(huán),還有圓環(huán)的寬度等(插一句,從屏幕左上角,向右為X軸正方向,向下為Y軸正方向)

//實心圓
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);//開啟抗鋸齒
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(200,200, 150, paint);
//空心圓
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(700, 200, 150, paint);
//藍色實心圓
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(700, 600, 150, paint);
//空心圓環(huán),環(huán)寬20
paint.setStrokeWidth(20);
canvas.drawCircle(200, 600, 150, paint);
3.canvas.drawRect(float left, float top, float right, float bottom, Paint paint)畫矩形

canvas.drawRect(100,100,400,300,paint);
從上面可以很明顯的看到各個參數(shù)所代表的意思。矩形的width = right-left,矩形的hight = bottom-top。當寬和高相等時就是正方形。例如,我要畫一個寬為300,高為200的矩形,是這樣的canvas.drawRect(100,100,400,300,paint)
4.canvas.drawPoint(float x, float y, Paint paint)畫點
x 和 y 是點的坐標。點的大小可以通過 paint.setStrokeWidth(width) 來設(shè)置;點的形狀可以通過 paint.setStrokeCap(cap) 來設(shè)置:ROUND 畫出來是圓形的點,SQUARE 或 BUTT 畫出來是方形的點。

//圓點
paint.setColor(Color.BLACK);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(60);
canvas.drawPoint(200, 200, paint);
方點
paint.setStrokeCap(Paint.Cap.SQUARE);
paint.setStrokeWidth(60);
canvas.drawPoint(500,200,paint);
drawPoint()是畫單個點,還有兩個方法是批量畫點,drawPoints(float[] pts, int offset, int count, Paint paint) / drawPoints(float[] pts, Paint paint),
float[] points = {0, 0, 50, 50, 50, 100, 100, 50, 100, 100, 150, 50, 150, 100};每兩個數(shù)字為一個點
// 繪制四個點:(50, 50) (50, 100) (100, 50) (100, 100)
canvas.drawPoints(points, 2 /* 跳過兩個數(shù),即前兩個 0 */, 4 /* 坐標個數(shù),也就是兩個點*/, paint);
//繪制所有的點
canvas.drawPoints(points,paint);
5.canvas.drawOval(float left, float top, float right, float bottom, Paint paint)畫橢圓
left, top, right, bottom 是這個橢圓的左、上、右、下四個邊界點的坐標

//實心橢圓
paint.setStyle(Style.FILL);
canvas.drawOval(50, 50, 350, 200, paint);
//空心橢圓
paint.setStyle(Style.STROKE);
canvas.drawOval(400, 50, 700, 200, paint);
6.canvas.drawLine(float startX, float startY, float stopX, float stopY, Paint paint)畫線
前兩個參數(shù)是線的起點坐標,然后兩個是終點坐標。

paint.setStrokeWidth(20);//設(shè)置線寬
canvas.drawLine(100, 100, 600, 500, paint);paint
畫線跟畫點類似,也有批量畫線的方法drawLines(float[] pts, int offset, int count, Paint paint) / drawLines(float[] pts, Paint paint)
float[] points = {20, 20, 120, 20, 70, 20, 70, 120, 20, 120, 120, 120, 150, 20, 250, 20, 150, 20, 150, 120, 250, 20, 250, 120, 150, 120, 250, 120};
canvas.drawLines(points, paint); //畫所有線
canvas.drawPoints(points, 2 /* 跳過兩條線,即4個點,8個數(shù)字 */, 3 /* 一共繪制三個點*/, paint);
7.canvas.drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint)畫圓角矩形
left, top, right, bottom 是四條邊的坐標,rx 和 ry 是圓角的橫向半徑和縱向半徑。

//實心圓角矩形
canvas.drawRoundRect(100,100,600,300,30,30,paint);(設(shè)置paint填充模式可畫空心圓角矩形)
8.canvas.drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint) 繪制弧形或扇形
drawArc() 是使用一個橢圓來描述弧形的。left, top, right, bottom 描述的是這個弧形所在的橢圓;startAngle 是弧形的起始角度(x 軸的正向,即正右的方向,是 0 度的位置;順時針為正角度,逆時針為負角度),sweepAngle 是弧形劃過的角度;useCenter 表示是否連接到圓心,如果不連接到圓心,就是弧形,如果連接到圓心,就是扇形。

paint.setStyle(Paint.Style.FILL); // 填充模式
canvas.drawArc(200, 100, 800, 500, -110, 100, true, paint); // 繪制扇形
canvas.drawArc(200, 100, 800, 500, 20, 140, false, paint); // 繪制弧形
paint.setStyle(Paint.Style.STROKE); // 畫線模式
canvas.drawArc(200, 100, 800, 500, 180, 60, false, paint); // 繪制不封口的弧形
9.canvas.drawPath(Path path, Paint paint) 畫自定義圖形(重點來了)
Path 可以描述直線、二次曲線、三次曲線、圓、橢圓、弧形、矩形、圓角矩形。把這些圖形結(jié)合起來,就可以描述出很多復(fù)雜的圖形。Path 有兩類方法,一類是直接描述路徑的,另一類是輔助的設(shè)置或計算。(詳細解釋請點這里)
下面來重點分析下這個心形是怎么畫的

Path path = new Path(); // 初始化 Path 對象
//第一步,path添加左邊一個扇形
path.addArc(200, 200, 400, 400, -225, 225);
//第二步,從第一步完成的地方添加右邊的扇形
path.arcTo(400, 200, 600, 400, -180, 225, false);
//第三步,從第二部步結(jié)束的地方畫線,到點(400,542)也就是心形最下面的點,并與起點封閉封閉
path.lineTo(400, 542);
//畫圖
canvas.drawPath(path, paint);
path可以添加各種形狀,然后相互連接起來。


更多的方法,大家可以自己研究研究。
10.canvas.drawBitmap(Bitmap bitmap, float left, float top, Paint paint) 畫 Bitmap
繪制 Bitmap 對象,也就是把這個 Bitmap 中的像素內(nèi)容貼過來。其中 left 和 top 是要把 bitmap 繪制到的位置坐標。
canvas.drawBitmap(bitmap, 200, 100, paint);
11.canvas.drawText(String text, float x, float y, Paint paint) 繪制文字
界面里所有的顯示內(nèi)容,都是繪制出來的,包括文字。 drawText() 這個方法就是用來繪制文字的。參數(shù) text 是用來繪制的字符串,x 和 y 是繪制的起點坐標。
通過 Paint.setTextSize(textSize),可以設(shè)置文字的大小。
paint.setTextSize(18);
canvas.drawText(text, 100, 25, paint);
paint.setTextSize(36);
canvas.drawText(text, 100, 70, paint);
12.畫柱狀圖和餅圖

這些復(fù)雜的圖形其實就是把前面講到的方法綜合起來用就可以繪制成想要的圖形了。把一些基本的封裝起來,再把一些可以設(shè)置值和顏色的方法暴露出去,就成了自己的自定義控件。
推薦兩個圖表類的開源項目,一個android的MPAndroidChart,一個h5頁面上可以用的ECharts。
以上所有的代碼在這里
另外強烈推薦大家關(guān)注下扔物線大神的公眾號,這是一個系列的教程,每周一篇。
