自定義View ——Canvas之繪制基本形狀##
轉載出處:http://www.gcssloop.com/customview/Canvas_Convert/
一.Canvas簡介###
Canvas 稱之為畫布,是安卓平臺2D圖形繪制的基礎姑廉,非常強大。
一般來說,比較基礎的東西有兩大特點:
1.可操作性強:由于這些是構成上層的基礎景用,所以可操作性必然十分強大。
2.比較難用:各種方法太過基礎惭蹂,想要完美的將這些操作組合起來有一定難度伞插。
本系列文章不僅會介紹到Canvas的操作方法,還會簡單介紹一些設計思路和技巧盾碗。
二.Canvas的常用操作速查表##
列表:
操作類型 | 相關API | 備注 |
---|---|---|
繪制顏色 | drawColor,drawRGB,drawARGB | 使用單一顏色填充整個畫布 |
繪制基本形狀 | drawPoint,drawPoints,drawLine,drawLines,drawRect,drawRountRect,drawOval,drawCircle,drawArc | 依次為點媚污、線、矩形廷雅、圓角矩形耗美、橢圓、圓航缀、圓弧 |
繪制圖片 | drawBitmap,drawPicture | 繪制位圖和圖片 |
繪制文本 | drawText,drawPosText,drawTextOnPath | 依次為 繪制文字商架、繪制文字時指定每個文字位置、根據路徑繪制文字 |
頂點操作 | drawVertices,drawBitmapMesh | 通過對頂點操作可以使圖像形變芥玉,drawVertices直接對畫布作用蛇摸、drawBitmapMesh只對繪制的Bitmap作用 |
繪制路徑 | drawPath | 繪制路徑,繪制貝塞爾曲線時也需要用該函數 |
畫布剪裁 | clipPath,clipRect | 設置畫布的顯示區(qū)域 |
畫布快照 | save,restore,saveLayerXxx,restoreToCount,getSaveCount | 依次為保存當前狀態(tài)灿巧、回滾到上一次保存的狀態(tài)赶袄、保存圖層狀態(tài)揽涮、回滾到指定狀態(tài)、獲取保存次數 |
畫布變換 | translate,scale,rotate,skew | 依次為位移弃鸦、縮放绞吁、旋轉、錯切 |
Matrix矩陣 | getMatrix唬格、setMatrix家破、concat | 實際畫布的位移,縮放等操作的都是圖像矩陣Matrix购岗,只不過Matrix比較難以理解和使用汰聋,故封裝了一些常用的方法。 |
三喊积、Canvas詳解###
本篇內容主要講解如何利用Canvas繪制基本圖形烹困。
繪制顏色:
繪制顏色是填充整個畫布,常用于繪制底色乾吻。
代碼:
canvas.drawColor(Color.BLUE);//繪制藍色
如圖:
創(chuàng)建畫筆:
想繪制內容髓梅,首先需要先創(chuàng)建一個畫筆,如下:
//創(chuàng)建一個畫筆
private Paint mPaint=new Paint();
//初始化畫筆
private void initPaint(){
mPaint.setColor(Color.BLACK); //設置畫筆顏色
mPaint.setStyle(Paint.Style.FILL); //設置畫筆模式為填充
mPaint.setStrokeWidth(10f); //設置畫筆寬度為10px
}
//在構造函數中初始化
public SloopView(Context context,AttributeSet attrs){
super(context,attrs);
initPaint();
}
在創(chuàng)建完畫筆之后绎签,就可以在Canvas中繪制各種內容了枯饿。
繪制點:###
可以繪制一個點,也可以繪制一組點诡必,如下:
canvas.drawPoint(200,200,mPaint);
canvas.drawPoints(new float[]{
500,500,
500,600,
500,700
},mPaint);
關于坐標原點默認在左上角奢方,水平向右為x軸增大方向,豎直向下為y軸增大方向爸舒。
繪制直線:###
繪制直線只需要兩個點蟋字,初始點和結束點,同樣繪制直線也可以繪制一條或者繪制一組:
canvas.drawLine(300,300,500,500,mPaint);//在坐標(300,300)(500,600)之間繪制一條直線
canvas.drawLines(new float[]{ //繪制一組線 每四位數字(兩個點的坐標)確定一條線
100,200,200,200,
100,300,200,200
},mpaint);
繪制矩形:###
確定確定一個矩形最少需要四個數據扭勉,就是對角線的兩個點的坐標值鹊奖,這里一般采用左上角和右下角的兩個點的坐標。
關于繪制矩形剖效,Canvas提供了三種重載方法嫉入,第一種就是提供四個數值(矩形左上角和右下角兩個點的坐標)來確定一個矩形進行繪制。其余兩種是先將矩形封裝為Rect或者RectF(實際上仍然是用兩個坐標點來確定的矩形)璧尸,然后傳遞給Canvas繪制咒林,如下:
//第一種
canvas.drawRect(100,100,800,400,mPaint);
//第二種
Rect mRect=new Rect(100,100,800,400);
canvas.drawRect(mRect,mPaint);
//第三種
RectF mRectF=new RectF(100,100,800,400);
canvas.drawRect(mRectF,mPaint);
三種繪制的結果是完全一樣的。
繪制圓角矩形###
繪制圓角矩形也提供了兩種重載方式爷光,如下:
//第一種
RectF mRectF=new RectF(100,100,800,400);
canvas.drawRoundRect(mRectF,30,30,mPaint);
//第二種
canvas.drawRoundRect(100,100,800,400,30,30,mPaint);
第二種方法在API21的時候才添加上垫竞,所以我們一般使用的都是第一種。
與矩形相比,圓角矩形多出來了兩個參數rx和ry欢瞪,這里圓角矩形的角實際上不是一個正圓的圓弧活烙,而是橢圓的圓弧,這里的兩個參數實際上是橢圓的兩個半徑遣鼓,他們看起來如下圖:
紅線標注的rx與ry就是兩個半徑啸盏,也就是相比繪制矩形多出來的那兩個參數。
我們了解到原理后骑祟,就可以為所欲為了回懦,通過計算可知我們上次繪制的矩形寬度為700,高度為300次企,當你讓rx大于350(寬度的一半)怯晕,ry大于150(高度的一半)時奇跡就出現了,你會發(fā)現圓角矩形變成了一個橢圓缸棵,他們畫出來是這樣的(為了方便確認我更改了畫筆顏色舟茶,同時繪制出了矩形和圓角矩形):
//矩形
RectF mRectF=new RectF(100,100,800,400);
//繪制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(mRectF,mPaint);
//繪制圓角矩形
mPaint.setColor(Color.BLUE);
canvas.drawRoundRect(mRectF,700,400,mPaint);
其中灰色部分是我們所選定的矩形,而里面的圓角矩形則變成了一個橢圓堵第,實際上rx為寬度的一半吧凉,ry為高度的一半時,剛好是一個橢圓踏志,通過上面我們分析的原理推算一下就能得到客燕,而當rx大于寬度的一半,ry大于高度的一半時狰贯,實際上是無法計算出圓弧的,所以drawRoundRect對大于該數值的參數進行了限制赏廓,凡是大于一半的參數均按照一半來處理涵紊。
繪制橢圓:###
相對于繪制圓角矩形,繪制橢圓就簡單的多了幔摸,因為他只需要一個矩形作為參數:
//第一種
RectF rectF=new RectF(100,100,800,400);
canvas.drawOval(rectF,mPaint);
//第二種
canvas.drawOval(100,100,800,400,mPaint);
以上兩種方法效果完全一樣视乐,但一般使用第一種分蓖。
繪制橢圓實際上就是繪制一個矩形的內切圖形,原理如下:
繪制圓:###
如下:
canvas.drawCircle(500,500,400,mPaint);//繪制一個圓心坐標在(500,500),半徑為400的圓疮蹦。
繪制圓形有四個參數,前兩個是圓心坐標前硫,第三個是半徑淮野,最后一個是畫筆。
繪制圓豢林ā:
// 第一種
public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint){}
// 第二種
public void drawArc(float left, float top, float right, float bottom, float startAngle,
float sweepAngle, boolean useCenter, @NonNull Paint paint) {}
從上面可以看出酪术,相比于繪制橢圓,繪制圓弧還多了三個參數:
startAngle //開始角度
sweepAngle //掃過角度
useCenter //是否使用中心
上代碼:
RectF rectF = new RectF(100,100,800,400);
// 繪制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(rectF,mPaint);
// 繪制圓弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF,0,90,false,mPaint);
//-------------------------------------
RectF rectF2 = new RectF(100,600,800,900);
// 繪制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(rectF2,mPaint);
// 繪制圓弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF2,0,90,true,mPaint);
上述代碼實際上是繪制了一個起始角度為0度,掃過90度的圓弧绘雁,兩者的區(qū)別就是是否使用了中心點橡疼,結果如下:
相比于使用橢圓,我們還是使用正圓比較多的庐舟,使用正圓展示一下效果:
RectF rectF= new RectF(100,100,800,400);
//繪制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(rectF,mPaint);
//繪制圓弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF,0,90,false,mPaint);
//-----------------------------------------------------
RectF rectF2= new RectF(100,600,800,900);
//繪制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(rectF2,mPaint);
//繪制圓弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF2,0,90,true,mPaint);
簡要介紹Paint###
看了上面這么多欣除,相信有一部分人會產生一個疑問,如果我想繪制一個圓挪略,只要邊不要里面的顏色怎么辦历帚?
很簡單,繪制的基本形狀由Canvas確定瘟檩,但繪制出來的顏色抹缕,具體效果則由Paint確定。
mPaint.setStyle(Paint.Style.FILL);//設置畫筆模式為填充
為了展示方便墨辛,容易看出效果卓研,之前使用的模式一直為填充模式,實際上畫筆有三種模式睹簇,如下:
STROKE //描邊
FILL //填充
FILL_AND_STROKE //描邊加填充
為了區(qū)分三者效果我們做如下實驗:
Paint paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(40);
//描邊
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(200,200,100,paint);
//填充
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(200,500,100,paint);
//描邊加填充
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawCircle(200,800,100,paint);