三個繪圖工具類詳解
本節引言:
上兩小節我們學習了Drawable以及Bitmap,都是載入好圖片的,而本節我們要學習的繪圖相關的 有些API,他們分別是Canvas(畫布),Paint(畫筆),Path(路徑)!本節非常重要,同時也是我們 自訂View的基礎哦~好的,話不多說開始本節內容~
1.相關方法詳解
1)Paint(畫筆):
就是畫筆,用於設定繪製風格,如:線寬(筆觸粗細),顏色,透明度和填滿風格等 直接使用無參構造方法就可以創建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( ):清除陰影層 其他的自行查閱文件~
2)Canvas(畫布):
畫筆有了,接著就到畫筆(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指旋轉的角度,順時針旋轉
3)Path(路徑)
#簡單點說就是描點,連線~在創建好我們的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類別!移動移動畫筆
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 為結束角度。
2.動手試試:
屬性那麼多,一定要手把手的擼一下,才能加深我們的映像是吧~ 嘿嘿,畫圖要嘛在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中~
1)設定畫布顏色:
canvas.drawColor(getResources().getColor(R.color.yellow)); //设置画布背景颜色
2)繪製圓形:
canvas.drawCircle(200, 200, 100, mPaint); //画实心圆
3)繪製矩形:
canvas.drawRect(0, 0, 200, 100, mPaint); //画矩形
4)繪製Bitmap:
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher), 0, 0, mPaint);
#5)繪製弧形區域:
##
canvas.drawArc(new RectF(0, 0, 100, 100),0,90,true,mPaint); //绘制弧形区域假如true改為false:
6)繪製圓角矩形
canvas.drawRoundRect(new RectF(10,10,210,110),15,15,mPaint); //画圆角矩形
7 )繪製橢圓
canvas.drawOval(new RectF(0,0,200,300),mPaint); //画椭圆
8)繪製多邊形:
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);##9)繪製文字:
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); //绘制文字
##10)繪製自訂的圖形:
程式碼來自網路:
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(路徑)進行 了學習,方法有很多,別去死記,用到的時候查就好,這裡我們先有個大概映像即可,自訂控制項那裡 我們再來慢慢糾結~好的,就說這麼多,謝謝~