- 通過重寫View.onDraw方法
- 自己創建一個Canvas對象
- 調用SurfaceHolder.lockCanvas(),返回一個Canvas 在 surfaceView 或 TextureView中使用
自己創建一個Canvas 方法如下:
//得到一個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);
*/
/**
* 保存當前的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;// 圖層的 clip 標記,
public static final int FULL_COLOR_LAYER_SAVE_FLAG = 0x08;// 圖層的 color 標記,
public static final int CLIP_TO_LAYER_SAVE_FLAG = 0x10;// 圖層的 clip 標記,在saveLayer 和 saveLayerAlpha Android強烈建議必須加上他
public static final int ALL_SAVE_FLAG = 0x1F; //還原所有 一般情況都是使用這個
/*關於saveLayer的具體flags還不大明白它的含義,具體怎麼使用在下面例子中*/
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)
public class LayersTestView extends View {
public static final String TAG = "LayersTestView";
private Paint mPaint;
public LayersTestView(Context context) {
super(context);
init();
}
public LayersTestView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public LayersTestView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
mPaint.setColor(Color.RED);
canvas.drawCircle(75, 75, 75, mPaint);
canvas.translate(25, 25);
LogUtil.d(TAG, "getCounet2 = " + canvas.getSaveCount());
int count = canvas.saveLayerAlpha(0, 0, 200, 200, 0x88, Canvas.ALL_SAVE_FLAG);
LogUtil.d(TAG, "count = " + count + " , getCounet2 = " + canvas.getSaveCount());
mPaint.setColor(Color.BLUE);
canvas.drawCircle(125, 125, 75, mPaint);
canvas.restore();
canvas.drawCircle(30, 30, 30, mPaint);
LogUtil.d(TAG, "getCounet3 = " + canvas.getSaveCount());
}
}
- 我調用的canvas.translate(10, 10); 即把 畫布平移 對 新建的那個圖層是依然生效的.
- 我們調用 saveLayerAlpha方法, 也會和 save 方法一樣, 不僅在 layer 的那個棧中壓入一個圖層, 同時在還會在 上面 說 save 和 restore 那裏壓入一個棧.