Canvas 的主要結構是一個位圖矩陣(從起構造參數須要一個位圖Bitmap就可推斷), 當進行 save 、savelayerXX的時候,會建立一個新的位圖矩陣(大小和原來同樣,可是不包含原來矩陣的內容,即沒有渲染),調用restore、restoreXX的時候,會把當前操做的矩陣內容合併到其下層的矩陣,並把當前矩陣丟棄(彈出),並把其下層的矩陣設置當前矩陣。java
伴隨每個位圖矩陣,還有一個變換矩陣(可經過canvas.getMatrix 獲得),當進行 translate、rotate、scale等操做時,改變的是變換矩陣,每次進行渲染時(drawXX),都會使用變換矩陣, 因此translate、rotate、scale等變換操做要在drawXX以前調用, 不然不起做用。canvas
一個畫圖須要四大基本要素:ide
一、一個用來保存像素的Bitmap;動畫
二、一個Canvas畫布,繪製Bitmap操做;this
三、繪製的東西spa
四、繪製的畫筆Paint(顏色和樣式).net
Canvas對象的獲取方式有三種:rest
第一種咱們經過重寫View.onDraw方法,View中的Canvas對象會被當作參數傳遞過來,咱們操做這個Canvas,效果會直接反應在View中。code
第二種就是當你想本身建立一個Canvas對象。從上面的基本要素能夠明白,一個Canvas對象必定是結合了一個Bitmap對象的。因此必定要爲一個Canvas對象設置一個Bitmap對象。orm
//獲得一個Bitmap對象,固然也可使用別的方式獲得。可是要注意,改bitmap必定要是mutable(異變的) Bitmap b = Bitmap.createBitmap(100,100, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(b); /*先new一個Canvas對象,在調用setBitmap方法,同樣的效果 * Canvas c = new Canvas(); * c.setBitmap(b); */
第三種方式,是調用SurfaceHolder.lockCanvas(),返回一個Canvas對象。
1)填充
drawARGB(int a, int r, int g, int b) drawColor(int color) drawRGB(int r, int g, int b) drawColor(int color, PorterDuff.Mode mode)
2)幾何圖形
canvas.drawArc (扇形) canvas.drawCircle(圓) canvas.drawOval(橢圓) canvas.drawLine(線) canvas.drawPoint(點) canvas.drawRect(矩形) canvas.drawRoundRect(圓角矩形) canvas.drawVertices(頂點) cnavas.drawPath(路徑)
3)圖片
canvas.drawBitmap (位圖) canvas.drawPicture (圖片)
4)文本
canvas.drawText
爲了方便一些轉換操做,Canvas還提供了保存和回滾屬性的方法(save和restore),好比你能夠先保存目前畫紙的位置(save),而後旋轉90度,向下移動100像素後畫一些圖形,畫完後調用restore方法返回到剛纔保存的位置。
Canvas提供的該功能的API以下:
/** * 保存當前的matrix和clip到私有的棧中(Skia內部實現)。任何matrix變換和clip操做都會在調用restore的時候還原。 * @return 返回值能夠傳入到restoreToCount()方法,以返回到某個save狀態以前。 */ public native int save(); /** * 傳入一個標誌,來表示當restore 的時候,哪些參數須要還原。該參數定義在Canvas中,參照下面。 * save()方法默認的是還原matrix和clip,可是可使用這個方法指定哪些須要還原。而且只有指定matrix和clip纔有效,其他的幾個參數是 * 用於saveLayer()和saveLayerAlpha()方法 的。 */ public native int save(int saveFlags); /** * 回到上一個save調用以前的狀態,若是restore調用的次數大於save方法,會出錯。 */ public native void restore(); /** * 返回棧中保存的狀態,值等譯 save()調用次數-restore()調用次數 */ public native int getSaveCount(); /** * 回到任何一個save()方法調用以前的狀態 */ public native void restoreToCount(int saveCount); /**saveFlags的參數*/ public static final int MATRIX_SAVE_FLAG = 0x01;//須要還原Matrix public static final int CLIP_SAVE_FLAG = 0x02;//須要還原Clip public static final int HAS_ALPHA_LAYER_SAVE_FLAG = 0x04; public static final int FULL_COLOR_LAYER_SAVE_FLAG = 0x08; public static final int CLIP_TO_LAYER_SAVE_FLAG = 0x10; public static final int ALL_SAVE_FLAG = 0x1F; //還原全部 /*saveLayer*/ public int saveLayer(RectF bounds, Paint paint, int saveFlags) public int saveLayer(float left, float top, float right, float bottom, Paint paint, int saveFlags) public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha, int saveFlags)
saveLayer
Canvas 在通常的狀況下能夠看做是一張畫布,全部的繪圖操做如drawBitmap, drawCircle都發生在這張畫布上,這張畫板還定義了一些屬性好比Matrix,顏色等等。可是若是須要實現一些相對複雜的繪圖操做,好比多層動畫,地圖(地圖能夠有多個地圖層疊加而成,好比:政區層,道路層,興趣點層)。Canvas提供了圖層(Layer)支持,缺省狀況能夠看做是隻有一個圖層Layer。若是須要按層次來繪圖,Android的Canvas可使用SaveLayerXXX, Restore 來建立一些中間層,對於這些Layer是按照「棧結構「來管理的:
建立一個新的Layer到「棧」中,可使用saveLayer, savaLayerAlpha, 從「棧」中推出一個Layer,可使用restore,restoreToCount。但Layer入棧時,後續的DrawXXX操做都發生在這個Layer上,而Layer退棧時,就會把本層繪製的圖像「繪製」到上層或是Canvas上,在複製Layer到Canvas上時,能夠指定Layer的透明度(Layer),這是在建立Layer時指定的:public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags)本例Layers 介紹了圖層的基本用法:Canvas能夠看作是由兩個圖層(Layer)構成的,爲了更好的說明問題,咱們將代碼稍微修改一下,缺省圖層繪製一個紅色的圓,在新的圖層畫一個藍色的圓,新圖層的透明度爲0×88。
public class Layers extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new SampleView(this)); } private static class SampleView extends View { private static final int LAYER_FLAGS = Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG; private Paint mPaint; public SampleView(Context context) { super(context); setFocusable(true); mPaint = new Paint(); mPaint.setAntiAlias(true); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(Color.WHITE); canvas.translate(10, 10); mPaint.setColor(Color.RED); canvas.drawCircle(75, 75, 75, mPaint); canvas.saveLayerAlpha(0, 0, 200, 200, 0x88, LAYER_FLAGS); mPaint.setColor(Color.BLUE); canvas.drawCircle(125, 125, 75, mPaint); canvas.restore(); } } }
參考:http://blog.csdn.net/linghu_java/article/details/8939952