編輯:Android技術基礎
上兩小節我們學習了Drawable以及Bitmap,都是加載好圖片的,而本節我們要學習的繪圖相關的 一些API,他們分別是Canvas(畫布),Paint(畫筆),Path(路徑)!本節非常重要,同時也是我們 自定義View的基礎哦~好的,話不多說開始本節內容~
官方API文檔:Canvas;Paint;Path;
就是畫筆,用於設置繪制風格,如:線寬(筆觸粗細),顏色,透明度和填充風格等 直接使用無參構造方法就可以創建Paint實例: Paint paint = new Paint( );
我們可以通過下述方法來設置Paint(畫筆)的相關屬性,另外,關於這個屬性有兩種, 圖形繪制相關與文本繪制相關:
- setARGB(int a,int r,int g,int b): 設置繪制的顏色,a代表透明度,r,g,b代表顏色值。
- setAlpha(int a): 設置繪制圖形的透明度。
- setColor(int color): 設置繪制的顏色,使用顏色值來表示,該顏色值包括透明度和RGB顏色。
- setAntiAlias(boolean aa): 設置是否使用抗鋸齒功能,會消耗較大資源,繪制圖形速度會變慢。
- setDither(boolean dither): 設定是否使用圖像抖動處理,會使繪制出來的圖片顏色更加平滑和飽滿,圖像更加清晰
- setFilterBitmap(boolean filter): 如果該項設置為true,則圖像在動畫進行中會濾掉對Bitmap圖像的優化操作, 加快顯示速度,本設置項依賴於dither和xfermode的設置
- setMaskFilter(MaskFilter maskfilter): 設置MaskFilter,可以用不同的MaskFilter實現濾鏡的效果,如濾化,立體等
- setColorFilter(ColorFilter colorfilter): 設置顏色過濾器,可以在繪制顏色時實現不用顏色的變換效果
- setPathEffect(PathEffect effect) 設置繪制路徑的效果,如點畫線等
- setShader(Shader shader): 設置圖像效果,使用Shader可以繪制出各種漸變效果
- setShadowLayer(float radius ,float dx,float dy,int color):在圖形下面設置陰影層,產生陰影效果, radius為陰影的角度,dx和dy為陰影在x軸和y軸上的距離,color為陰影的顏色
- setStyle(Paint.Style style): 設置畫筆的樣式,為FILL,FILL_OR_STROKE,或STROKE
- setStrokeCap(Paint.Cap cap): 當畫筆樣式為STROKE或FILL_OR_STROKE時,設置筆刷的圖形樣式, 如圓形樣Cap.ROUND,或方形樣式Cap.SQUARE
- setSrokeJoin(Paint.Join join): 設置繪制時各圖形的結合方式,如平滑效果等
- setStrokeWidth(float width): 當畫筆樣式為STROKE或FILL_OR_STROKE時,設置筆刷的粗細度
- setXfermode(Xfermode xfermode): 設置圖形重疊時的處理方式,如合並,取交集或並集,經常用來制作橡皮的擦除效果
- setFakeBoldText(boolean fakeBoldText): 模擬實現粗體文字,設置在小字體上效果會非常差
- setSubpixelText(boolean subpixelText): 設置該項為true,將有助於文本在LCD屏幕上的顯示效果
- setTextAlign(Paint.Align align): 設置繪制文字的對齊方向
- setTextScaleX(float scaleX): 設置繪制文字x軸的縮放比例,可以實現文字的拉伸的效果
- setTextSize(float textSize): 設置繪制文字的字號大小
- setTextSkewX(float skewX): 設置斜體文字,skewX為傾斜弧度
- setTypeface(Typeface typeface): 設置Typeface對象,即字體風格,包括粗體,斜體以及襯線體,非襯線體等
- setUnderlineText(boolean underlineText): 設置帶有下劃線的文字效果
- setStrikeThruText(boolean strikeThruText): 設置帶有刪除線的效果
- setStrokeJoin(Paint.Join join): 設置結合處的樣子,Miter:結合處為銳角, Round:結合處為圓弧:BEVEL:結合處為直線
- setStrokeMiter(float miter):設置畫筆傾斜度
- setStrokeCap (Paint.Cap cap):設置轉彎處的風格 其他常用方法:
- float ascent( ):測量baseline之上至字符最高處的距離
- float descent():baseline之下至字符最低處的距離
- int breakText(char[] text, int index, int count, float maxWidth, float[] measuredWidth): 檢測一行顯示多少文字
- clearShadowLayer( ):清除陰影層 其他的自行查閱文檔~
畫筆有了,接著就到畫布(Canvas),總不能憑空作畫是吧~常用方法如下:
首先是構造方法,Canvas的構造方法有兩種:
Canvas(): 創建一個空的畫布,可以使用setBitmap()方法來設置繪制具體的畫布。
Canvas(Bitmap bitmap): 以bitmap對象創建一個畫布,將內容都繪制在bitmap上,因此bitmap不得為null。
接著是 1.drawXXX()方法族:以一定的坐標值在當前畫圖區域畫圖,另外圖層會疊加, 即後面繪畫的圖層會覆蓋前面繪畫的圖層。 比如:
- drawRect(RectF rect, Paint paint) :繪制區域,參數一為RectF一個區域
- drawPath(Path path, Paint paint) :繪制一個路徑,參數一為Path路徑對象
- drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) : 貼圖,參數一就是我們常規的Bitmap對象,參數二是源區域(這裡是bitmap), 參數三是目標區域(應該在canvas的位置和大小),參數四是Paint畫刷對象, 因為用到了縮放和拉伸的可能,當原始Rect不等於目標Rect時性能將會有大幅損失。
- drawLine(float startX, float startY, float stopX, float stopY, Paintpaint) : 畫線,參數一起始點的x軸位置,參數二起始點的y軸位置,參數三終點的x軸水平位置, 參數四y軸垂直位置,最後一個參數為Paint 畫刷對象。
- drawPoint(float x, float y, Paint paint): 畫點,參數一水平x軸,參數二垂直y軸,第三個參數為Paint對象。
- drawText(String text, float x, floaty, Paint paint) : 渲染文本,Canvas類除了上面的還可以描繪文字,參數一是String類型的文本, 參數二x軸,參數三y軸,參數四是Paint對象。
- drawOval(RectF oval, Paint paint):畫橢圓,參數一是掃描區域,參數二為paint對象;
- drawCircle(float cx, float cy, float radius,Paint paint): 繪制圓,參數一是中心點的x軸,參數二是中心點的y軸,參數三是半徑,參數四是paint對象;
- drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint): 畫弧,參數一是RectF對象,一個矩形區域橢圓形的界限用於定義在形狀、大小、電弧,參數二是起始角 (度)在電弧的開始,參數三掃描角(度)開始順時針測量的,參數四是如果這是真的話,包括橢圓中心的電 弧,並關閉它,如果它是假這將是一個弧線,參數五是Paint對象;
2.clipXXX()方法族:在當前的畫圖區域裁剪(clip)出一個新的畫圖區域,這個畫圖區域就是canvas 對象的當前畫圖區域了。比如:clipRect(new Rect()),那麼該矩形區域就是canvas的當前畫圖區域
3.save()和restore()方法: save( ):用來保存Canvas的狀態。save之後,可以調用Canvas的平移、放縮、旋轉、錯切、裁剪等操作! restore():用來恢復Canvas之前保存的狀態。防止save後對Canvas執行的操作對後續的繪制有影響。 save()和restore()要配對使用(restore可以比save少,但不能多),若restore調用次數比save多,會報錯!
4.translate(float dx, float dy): 平移,將畫布的坐標原點向左右方向移動x,向上下方向移動y.canvas的默認位置是在(0,0)
5.scale(float sx, float sy):擴大,x為水平方向的放大倍數,y為豎直方向的放大倍數
6.rotate(float degrees):旋轉,angle指旋轉的角度,順時針旋轉
簡單點說就是描點,連線~在創建好我們的Path路徑後,可以調用Canvas的drawPath(path,paint) 將圖形繪制出來~常用方法如下:
- addArc(RectF oval, float startAngle, float sweepAngle:為路徑添加一個多邊形
- addCircle(float x, float y, float radius, Path.Direction dir):給path添加圓圈
- addOval(RectF oval, Path.Direction dir):添加橢圓形
- addRect(RectF rect, Path.Direction dir):添加一個區域
- addRoundRect(RectF rect, float[] radii, Path.Direction dir):添加一個圓角區域
- isEmpty():判斷路徑是否為空
- transform(Matrix matrix):應用矩陣變換
- transform(Matrix matrix, Path dst):應用矩陣變換並將結果放到新的路徑中,即第二個參數。
更高級的效果可以使用PathEffect類!
幾個To:
- moveTo(float x, float y):不會進行繪制,只用於移動移動畫筆
- lineTo(float x, float y):用於直線繪制,默認從(0,0)開始繪制,用moveTo移動! 比如 mPath.lineTo(300, 300); canvas.drawPath(mPath, mPaint);
- quadTo(float x1, float y1, float x2, float y2): 用於繪制圓滑曲線,即貝塞爾曲線,同樣可以結合moveTo使用!
- rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3) 同樣是用來實現貝塞爾曲線的。 (x1,y1) 為控制點,(x2,y2)為控制點,(x3,y3) 為結束點。 Same as cubicTo, but the coordinates are considered relative to the current point on this contour.就是多一個控制點而已~ 繪制上述的曲線: mPath.moveTo(100, 500); mPath.cubicTo(100, 500, 300, 100, 600, 500); 如果不加上面的那個moveTo的話:則以(0,0)為起點,(100,500)和(300,100)為控制點繪制貝塞爾曲線
- arcTo(RectF oval, float startAngle, float sweepAngle): 繪制弧線(實際是截取圓或橢圓的一部分)ovalRectF為橢圓的矩形,startAngle 為開始角度, sweepAngle 為結束角度。
屬性那麼多,肯定要手把手的撸一下,才能加深我們的映像是吧~ 嘿嘿,畫圖要麼在View上畫,要麼在SurfaceView上畫,這裡我們在View上畫吧, 我們定義一個View類,然後再onDraw()裡完成繪制工作!
/** * Created by Jay on 2015/10/15 0015. */ public class MyView extends View{ private Paint mPaint; public MyView(Context context) { super(context); init(); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init(){ mPaint = new Paint(); mPaint.setAntiAlias(true); //抗鋸齒 mPaint.setColor(getResources().getColor(R.color.puple));//畫筆顏色 mPaint.setStyle(Paint.Style.FILL); //畫筆風格 mPaint.setTextSize(36); //繪制文字大小,單位px mPaint.setStrokeWidth(5); //畫筆粗細 } //重寫該方法,在這裡繪圖 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } }
然後布局那裡設置下這個View就好,下述代碼都寫在onDrawable中~
canvas.drawColor(getResources().getColor(R.color.yellow)); //設置畫布背景顏色
canvas.drawCircle(200, 200, 100, mPaint); //畫實心圓
canvas.drawRect(0, 0, 200, 100, mPaint); //畫矩形
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher), 0, 0, mPaint);
canvas.drawArc(new RectF(0, 0, 100, 100),0,90,true,mPaint); //繪制弧形區域
假如true改為false:
canvas.drawRoundRect(new RectF(10,10,210,110),15,15,mPaint); //畫圓角矩形
canvas.drawOval(new RectF(0,0,200,300),mPaint); //畫橢圓
Path path = new Path(); path.moveTo(10, 10); //移動到 坐標10,10 path.lineTo(100, 50); path.lineTo(200,40); path.lineTo(300, 20); path.lineTo(200, 10); path.lineTo(100, 70); path.lineTo(50, 40); path.close(); canvas.drawPath(path,mPaint);
canvas.drawText("最喜歡看曹神日狗了~",50,50,mPaint); //繪制文字
你也可以沿著某條Path來繪制這些文字:
Path path = new Path(); path.moveTo(50,50); path.lineTo(100, 100); path.lineTo(200, 200); path.lineTo(300, 300); path.close(); canvas.drawTextOnPath("最喜歡看曹神日狗了~", path, 50, 50, mPaint); //繪制文字
代碼來源於網上:
protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.translate(canvas.getWidth()/2, 200); //將位置移動畫紙的坐標點:150,150 canvas.drawCircle(0, 0, 100, mPaint); //畫圓圈 //使用path繪制路徑文字 canvas.save(); canvas.translate(-75, -75); Path path = new Path(); path.addArc(new RectF(0,0,150,150), -180, 180); Paint citePaint = new Paint(mPaint); citePaint.setTextSize(14); citePaint.setStrokeWidth(1); canvas.drawTextOnPath("繪制表盤~", path, 28, 0, citePaint); canvas.restore(); Paint tmpPaint = new Paint(mPaint); //小刻度畫筆對象 tmpPaint.setStrokeWidth(1); float y=100; int count = 60; //總刻度數 for(int i=0 ; i <count ; i++){ if(i%5 == 0){ canvas.drawLine(0f, y, 0, y+12f, mPaint); canvas.drawText(String.valueOf(i/5+1), -4f, y+25f, tmpPaint); }else{ canvas.drawLine(0f, y, 0f, y +5f, tmpPaint); } canvas.rotate(360/count,0f,0f); //旋轉畫紙 } //繪制指針 tmpPaint.setColor(Color.GRAY); tmpPaint.setStrokeWidth(4); canvas.drawCircle(0, 0, 7, tmpPaint); tmpPaint.setStyle(Paint.Style.FILL); tmpPaint.setColor(Color.YELLOW); canvas.drawCircle(0, 0, 5, tmpPaint); canvas.drawLine(0, 10, 0, -65, mPaint); }
本節我們對android.graphics接口類下的三個繪圖API:Canvas(畫布),Paint(畫筆),Path(路徑)進行 了學習,方法有很多,別去死記,用到的時候查就好,這裡我們先有個大概映像即可,自定義控件那裡 我們再來慢慢糾結~好的,就說這麼多,謝謝~
本節引言:在Android基礎入門教程——8.3.1 三個繪圖工具類詳解的Paint方法中有這樣一個方法:setMaskFilter(MaskFil
本節引言:前兩節我們學了Bitmap和一些基本的繪圖API的屬性以及常用的方法,但心裡總覺得有點不踏實,總得寫點什麼加深下映像是吧,嗯,本節我們就來
本節引言:本節給大家帶來的是最後一個用於顯示信息的UI控件——PopupWindow(懸浮框),如果你想知道他長什麼樣子,你可以打開你手機的QQ,長
1.Activity,Window與View的關系好吧,本來就想了解下他們幾個的關系,然後手多多,然後就開始看起他們的調用過程來了...結果扣了兩個