完全自定義控件-Canvas之繪制基本形狀
一.簡介
Canvas 美[?k?nv?s] 畫布
Canvas繪圖有三個基本要素:Canvas、繪圖坐標系以及Paint。
- Canvas是畫布,我們通過Canvas的各種drawXXX方法將圖形繪制到Canvas上面,在drawXXX方法中我們需要傳入要繪制的圖形的坐標形狀,還要傳入一個畫筆Paint。
- drawXXX方法以及傳入其中的坐標決定了要繪制的圖形的形狀,比如drawCircle方法,用來繪制圓形,需要我們傳入圓心的x和y坐標,以及圓的半徑。
- drawXXX方法中傳入的畫筆Paint決定了繪制的圖形的一些外觀,比如是繪制的圖形的顏色,再比如是繪制圓面還是圓的輪廓線等。
- Canvas的drawXXX方法中傳入的各種坐標指的都是繪圖坐標系中的坐標。在初始狀況下,繪圖坐標系的坐標原點在View的左上角。
但繪圖坐標系可以改變,例如translate方法,可以平移坐標系。且坐標系的位移是基于當前位置移動,而不是每次基于屏幕左上角的(0,0)點移動。
二.Canvas的常用操作速查表
操作類型 | 相關API | 備注 |
---|---|---|
繪制顏色 | drawColor, drawRGB, drawARGB | 使用單一顏色填充整個畫布 |
繪制基本形狀 | drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc | 依次為 點、線、矩形、圓角矩形、橢圓、圓、圓弧 |
繪制圖片 | drawBitmap, drawPicture | 繪制位圖和圖片 |
繪制文本 | drawText, drawPosText, drawTextOnPath | 依次為 繪制文字、繪制文字時指定每個文字位置、根據路徑繪制文字 |
繪制路徑 | drawPath | 繪制路徑,繪制貝塞爾曲線時也需要用到該函數 |
頂點操作 | drawVertices, drawBitmapMesh | 通過對頂點操作可以使圖像形變,drawVertices直接對畫布作用、 drawBitmapMesh只對繪制的Bitmap作用 |
畫布剪裁 | clipPath, clipRect | 設置畫布的顯示區域 |
畫布快照 | save, restore, saveLayerXxx, restoreToCount, getSaveCount | 依次為 保存當前狀態、 回滾到上一次保存的狀態、 保存圖層狀態、 回滾到指定狀態、 獲取保存次數 |
畫布變換 | translate, scale, rotate, skew | 依次為 位移、縮放、 旋轉、錯切 |
Matrix(矩陣) | getMatrix, setMatrix, concat | 實際畫布的位移,縮放等操作的都是圖像矩陣Matrix,只不過Matrix比較難以理解和使用,故封裝了一些常用的方法。 |
三.實戰
繪制顏色 drawARGB:
繪制顏色是填充整個畫布,常用于繪制底色。
- 新建CanvasView類繼承View
- 重寫onDraw
public class CanvasView extends View {
//在代碼中定義和使用時用到的
public CanvasView(Context context) {
super(context);
}
//在xml中定義我們的自定義屬性時用到
public CanvasView(Context context, AttributeSet attrs) {
super(context, attrs);
}
//在View中畫出我們需要的內容
@Override
protected void onDraw(Canvas canvas) {
canvas.drawARGB(255, 139, 197, 186);
}
}</code></pre>

繪制畫布
繪制點 drawPoint:
- 在構造函數中初始化畫筆
- 重寫onDraw
public class CanvasView extends View {
private Paint mPaint;
//在代碼中定義和使用時用到的
public CanvasView(Context context) {
super(context);
init();
}
//在xml中定義我們的自定義屬性時用到
public CanvasView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
//在構造函數中初始化畫筆
private void init() {
mPaint = new Paint();
mPaint.setColor(Color.BLACK); //設置畫筆顏色
mPaint.setStyle(Paint.Style.FILL); //設置畫筆模式為填充
mPaint.setStrokeWidth(10f); //設置畫筆寬度為10px
}
//在View中畫出我們需要的內容
@Override
protected void onDraw(Canvas canvas) {
canvas.drawPoint(100, 100, mPaint); //在坐標(100,100)位置繪制一個點
canvas.drawPoints(new float[]{ //繪制一組點,坐標位置由float數組指定
200, 200,
300, 400,
400, 500
}, mPaint);
}
}</code></pre>

繪制點
繪制直線 drawLine:
protected void onDraw(Canvas canvas) {
mPaint.setColor(Color.GREEN);// 設置綠色
canvas.drawLine(60, 40, 100, 40, mPaint);// 畫線
canvas.drawLine(110, 40, 190, 80, mPaint);// 斜線
canvas.drawLines(new float[]{ // 繪制一組線 每四數字(兩個點的坐標)確定一條線
100,200,200,200,
100,300,200,300
},mPaint);
}

繪制直線
繪制矩形 drawRect:
確定確定一個矩形最少需要四個數據,就是對角線的兩個點的坐標值,這里一般采用左上角和右下角的兩個點的坐標。
protected void onDraw(Canvas canvas) {
//取得畫布的寬高
int canvasWidth = canvas.getWidth();
int canvasHeight = canvas.getHeight();
//設置畫筆的填充色是藍色
mPaint.setColor(Color.BLUE);
int left1 = 10;
int top1 = 10;
int right1 = canvasWidth / 3;
int bottom1 = canvasHeight /3;
canvas.drawRect(left1, top1, right1, bottom1, mPaint);
//修改畫筆顏色
mPaint.setColor(Color.RED);
int left2 = canvasWidth / 3 * 2;
int top2 = 10;
int right2 = canvasWidth - 10;
int bottom2 = canvasHeight / 3;
canvas.drawRect(left2, top2, right2, bottom2, mPaint);
}</code></pre>
- 簡單畫了下法國國旗

繪制矩形
繪制圓角矩形 drawRoundRect:
protected void onDraw(Canvas canvas) {
mPaint.setColor(0xff8bc5ba);//A:ff,R:8b,G:c5,B:ba
RectF rectF = new RectF(10,10,300,150);
//這里的圓弧是橢圓的圓弧,所以要設置橢圓的兩個半徑
canvas.drawRoundRect(rectF,10,10,mPaint);
}

rx,ry

繪制圓角矩形
繪制圓、圓環和橢圓 drawCircle、drawOval:
protected void onDraw(Canvas canvas) {
mPaint.setColor(0xff8bc5ba);
mPaint.setAntiAlias(true); //設置畫筆為抗鋸齒模式,不然畫出來太丑了
mPaint.setStyle(Paint.Style.FILL);//默認繪圖為填充模式
int canvasWidth = canvas.getWidth();
int canvasHeight = canvas.getHeight();
int halfCanvasWidth = canvasWidth / 2;
int R = canvasHeight / 9;
// 繪制一個矩形的內切橢圓
RectF rectF = new RectF(100, 10, 370, 150);
canvas.drawOval(rectF, mPaint);
// 繪制一個圓心坐標在(halfCanvasWidth,250),半徑為R 的圓
canvas.drawCircle(halfCanvasWidth, 250, R, mPaint);
//通過繪制兩個圓形成圓環
//1. 首先繪制大圓
canvas.drawCircle(halfCanvasWidth, 450, R, mPaint);
//2. 然后繪制小圓,讓小圓覆蓋大圓,形成圓環效果
int r = (int) (R * 0.75);
mPaint.setColor(0xffffffff);//將畫筆設置為白色,畫小圓
canvas.drawCircle(halfCanvasWidth, 450, r, mPaint);
//通過畫筆的描邊繪圖模式繪制圓環
mPaint.setColor(0xff8bc5ba);//設置顏色
mPaint.setStyle(Paint.Style.STROKE);//繪圖為描邊模式
float strokeWidth = (float) (R * 0.25); //設置線條寬度
mPaint.setStrokeWidth(strokeWidth);
canvas.drawCircle(halfCanvasWidth, 650, R, mPaint);
}</code></pre>

繪制圓、圓環、橢圓
- 簡要介紹Paint的模式
- STROKE 描邊,把邊給填充顏色
- FILL 填充,填充邊中的內容
- FILL_AND_STROKE 描邊加填充,就是把上面兩個合起來
繪制圓弧 drawArc:
Canvas中提供了drawArc方法用于繪制弧,這里的弧指兩種:弧面和弧線,弧面即用弧圍成的填充面,弧線即為弧面的輪廓線。
public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint){}
- oval是RecF類型的對象,其定義了橢圓的形狀。
- startAngle指的是繪制的起始角度,如果傳入的startAngle小于0或者大于等于360,那么用startAngle對360進行取模后作為起始繪制角度。
- sweepAngle指的是從startAngle開始沿著鐘表的順時針方向旋轉掃過的角度。如果sweepAngle大于等于360,那么會繪制完整的橢圓弧。如果sweepAngle小于0,那么會用sweepAngle對360進行取模后作為掃過的角度。
-
useCenter是個boolean值,如果為true,表示在繪制完弧之后,用橢圓的中心點連接弧上的起點和終點以閉合弧;如果值為false,表示在繪制完弧之后,弧的起點和終點直接連接,不經過橢圓的中心點。
protected void onDraw(Canvas canvas) {
int canvasWidth = canvas.getWidth();
int canvasHeight = canvas.getHeight();
//把畫布分成五份
float ovalHeight = canvasHeight / 5;
float left = 10 ;
float top = 0;
float right = canvasWidth - left;
float bottom= ovalHeight;
RectF rectF = new RectF(left, top, right, bottom);
mPaint.setAntiAlias(true); //抗鋸齒
mPaint.setStrokeWidth(5);//設置線寬
mPaint.setColor(0xff8bc5ba);//設置顏色
mPaint.setStyle(Paint.Style.FILL);//默認設置畫筆為填充模式
//繪制用drawArc繪制完整的橢圓
canvas.drawArc(rectF, 0, 360, true, mPaint);
//繪制橢圓的四分之一,起點是0度,到90度
canvas.translate(0, ovalHeight ); //繪圖坐標系平移操作,x軸移動0,y軸移動五分之一個畫布長度
canvas.drawArc(rectF, 0, 90, true, mPaint);
//繪制橢圓的四分之一,將useCenter設置為false
canvas.translate(0, ovalHeight );
canvas.drawArc(rectF, 0, 90, false, mPaint);
//繪制橢圓的四分之一,只繪制輪廓線
mPaint.setStyle(Paint.Style.STROKE);//設置畫筆為描邊模式
canvas.translate(0, ovalHeight );
canvas.drawArc(rectF, 0, 90, true, mPaint);
//繪制帶有輪廓線的橢圓的四分之一
//1. 先繪制橢圓的填充部分
mPaint.setStyle(Paint.Style.FILL);//設置畫筆為填充模式
canvas.translate(0, ovalHeight );
canvas.drawArc(rectF, 0, 90, true, mPaint);
//2. 再繪制橢圓的輪廓線部分
mPaint.setStyle(Paint.Style.STROKE);//設置畫筆為線條模式
mPaint.setColor(0xff0000ff);//設置輪廓線條為藍色
canvas.drawArc(rectF, 0, 90, true, mPaint);
}

繪制圓弧
自定義餅圖:
學了那么大堆基礎終于可以畫個能用的圖了

自定義餅圖
protected void onDraw(Canvas canvas) {
RectF rectF = new RectF(100, 100, 400, 400);
mPaint.setAntiAlias(true); //抗鋸齒
mPaint.setStrokeWidth(5);//設置線寬
mPaint.setColor(0xFFCCFF00);//設置顏色
mPaint.setStyle(Paint.Style.FILL);//默認設置畫筆為填充模式
canvas.drawArc(rectF, 0, 110, true, mPaint);
mPaint.setColor(0xff8bc5ba);//設置顏色
canvas.drawArc(rectF, 110, 50, true, mPaint);
mPaint.setColor( 0xFF800000);//設置顏色
canvas.drawArc(rectF, 160, 80, true, mPaint);
mPaint.setColor(0xFFFF8C69);//設置顏色
canvas.drawArc(rectF, 240, 120, true, mPaint);
}
這里是 項目地址
參考
http://blog.csdn.net/iispring/article/details/49770651
來自:http://www.jianshu.com/p/282958cdbf25
本文由用戶 nabb4738 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!