自定義View之Canvas的使用
Canvas是什麼?
Canvas顧名思義,就是畫布的意思.它在安卓中可以變換(旋轉,移動,縮放,錯切).在自定義View中,重寫onDraw時會傳入一個Canvas物件,我們可以用它來畫點(Point),線(Line),圓(Circle),文字(Text),圓弧(ARC),路徑(Path)等圖形.還可以暫時儲存畫布然後再次取出上次儲存的畫布進行操作.(畫布在不同的位置可以儲存,然後可以再次回到你想要回過去再繼續畫的地方,就可以省略計算把畫布移動到原來的位置).下面你就會知道了,不理解沒關係.
我們用Canvas來畫安卓中的2D圖形.通過巧妙的變換,能畫出一些很複雜的圖形.
Canvas怎麼用?
首先需要自定義一個View:
1.自定義類繼承View
2.重寫建構函式
3.重寫onDraw()方法
4.最後別忘了加到xml佈局檔案中
以下給出程式碼,至於下面測試部分,程式碼很多相同,只需修改onDraw函式中的內容即可
public class CanvasDemo extends View { private Paint mPaint; public CanvasDemo(Context context) { this(context,null); } public CanvasDemo(Context context, @Nullable AttributeSet attrs) { this(context, attrs,0); } public CanvasDemo(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initControl(); } private void initControl() { mPaint = new Paint(); // 抗鋸齒,就是讓圖形看上去沒有齒輪狀,看起來更柔和 mPaint.setAntiAlias(true); // 設定畫筆的風格 mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(Color.YELLOW); // 設定畫筆的線帽 mPaint.setStrokeCap(Paint.Cap.ROUND); // 設定畫筆折斷處的樣式 mPaint.setStrokeJoin(Paint.Join.ROUND); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 在此處修改下面的操作 } }
xml佈局檔案:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <xhj.zime.com.blogrect.CanvasDemo android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
這裡不討論畫筆的樣式(Style),線帽的樣式以及Join的樣式,下一篇文章介紹Paint的時候會具體介紹這些的作用以及用法,這裡我們只看Canvas相關的知識.
個人認為可以分為四個系列:
1.draw系列(畫)
2.clip系列(裁剪)
3.儲存與恢復系列
4.變換系列(錯切,旋轉,縮放,移動)
1.draw系列
通過api可以知道,drawXXX有很多,當然用法都是類似的,這裡演示主要的幾個,其他請物以類聚.
drawCircle:
canvas.translate(getWidth() / 2, getHeight() / 2);
canvas.drawCircle(0,0,100,mPaint);
畫圓,這裡我呼叫translate方法把畫布移到螢幕的中間,以便觀察所以做次變換.第一個引數為x軸移動距離,第二個引數為y軸移動距離
drawCircle中的引數含義:1.圓心x軸座標;2.圓心y軸座標;3.半徑;4.畫筆
drawLine:
canvas.translate(getWidth() / 2, getHeight() / 2);
mPaint.setStrokeWidth(30);
canvas.drawLine(0,0,100,100,mPaint);
drawText:
canvas.translate(getWidth() / 2, getHeight() / 2);
mPaint.setTextSize(25);
canvas.drawText("I am studying Android!",0,0,mPaint);
drawRect:
canvas.translate(getWidth() / 2, getHeight() / 2);
Rect rect = new Rect(0,0,200,200);
canvas.drawRect(rect,mPaint);
如果想要精度大的,就用RectF即可
drawOval:
RectF rectF = new RectF(0,0,100,200);
canvas.drawOval(rectF,mPaint);
drawArc:useCenter為false
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
RectF rectF = new RectF(0,0,100,200);
canvas.drawArc(rectF,-180,270,false,mPaint);
這裡說一下,Paint的風格設定為STROKE是描邊的意思,不會填充他的內容,設定描邊的寬度
drawArc的引數含義:
1.需要一個矩形來畫圓弧
2.開始的角度
3.掃過的角度
4.是否使用中心點,不使用就不會和中心點相連,如果為true,就會和中心點相連,直接看效果就一目瞭然
5.畫筆物件
drawArc:(useCenter為true)
canvas.translate(getWidth() / 2, getHeight() / 2);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
RectF rectF = new RectF(0,0,100,200);
canvas.drawArc(rectF,-180,270,true,mPaint);
drawPath:
canvas.translate(getWidth() / 2, getHeight() / 2);
Path path = new Path();
path.moveTo(-50,-50);
path.lineTo(50,50);
path.lineTo(200,50);
path.lineTo(300,10);
canvas.drawPath(path,mPaint);
Path類,這裡不是檔案的路徑類,而是單純的路徑類,moveTo方法表示將這個原點移動到某一個位置,然後用lineTo連線每一個點,如果最後沒有連線到原點,會自動連線到原點去.
有一個rMoveTo和rLineTo方法,表示的是相對移動,沒有就是絕對的,相對指的不是座標,而是相對上一個座標移動多少,而不是移動到哪個座標.
還有其他類似的draw方法,自行閱讀api文件解決,其實都差不多.drawTextOnPath只不過是沿著路徑寫字,java的命名我相信已經寫的非常清楚了.
2.clip系列
未完待續.....