標籤:android paint.cap paint.join porterduffxfermode
主要思想:
將一個view設計成多層:背景層,含中獎資訊等;
遮蓋層,用於刮獎,使用關聯一個Bitmap的Canvas
在該Bitmap上,使用它的canvas.drawPath的api來處理 手勢滑動(類似刮獎的動作)
使用paint.setXfermode 來進行消除手勢滑動地區
/** * author : stone * email : [email protected] * time : 15/7/28 11 01 */public class GuaView extends View { private Bitmap mBitmap; //遮蓋的圖層 private Canvas mCanvas; //繪製遮蓋圖層 private Paint mOuterPaint; private Path mPath; private float mLastX; private float mLastY; private Bitmap mCoverBitmap; //遮蓋圖 private int mWidth, mHeight; private Paint mInnerPaint; private String mInfo; public GuaView(Context context) { this(context, null); } public GuaView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { mPath = new Path(); mOuterPaint = new Paint(); mInnerPaint = new Paint(); mCoverBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fg_guaguaka); mInfo = "¥ 5 0 0"; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mWidth = mCoverBitmap.getWidth(); mHeight = mCoverBitmap.getHeight(); setMeasuredDimension(mWidth, mHeight); mBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mBitmap); mCanvas.drawBitmap(mCoverBitmap, 0, 0, null); setOuterPaint(); setInnerPaint(); } private void setInnerPaint() { mInnerPaint.setColor(Color.RED); mInnerPaint.setStyle(Paint.Style.STROKE); mInnerPaint.setStrokeCap(Paint.Cap.ROUND); mInnerPaint.setStrokeJoin(Paint.Join.ROUND); mInnerPaint.setAntiAlias(true); mInnerPaint.setDither(true); //防抖 mInnerPaint.setStrokeWidth(5); mInnerPaint.setTextSize(100); mInnerPaint.setTextAlign(Paint.Align.CENTER); } private void setOuterPaint() { mOuterPaint.setColor(Color.GREEN); mOuterPaint.setStyle(Paint.Style.STROKE); mOuterPaint.setStrokeCap(Paint.Cap.ROUND); mOuterPaint.setStrokeJoin(Paint.Join.ROUND); mOuterPaint.setAntiAlias(true); mOuterPaint.setDither(true); //防抖 mOuterPaint.setStrokeWidth(20); } @Override //Path public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mLastX = x; mLastY = y; mPath.moveTo(x, y); break; case MotionEvent.ACTION_MOVE: float deltaX = Math.abs(x - mLastX); float deltaY = Math.abs(y - mLastY); if (deltaX > 5 || deltaY > 5) { mPath.lineTo(x, y); } mLastX = x; mLastY = y; break; case MotionEvent.ACTION_UP: break; } invalidate();//調用onDraw return true; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.parseColor("#bbbbbb")); //背景底色 灰色 canvas.drawText(mInfo, mWidth / 2, mHeight / 4 * 3, mInnerPaint); //繪製文本 canvas.drawBitmap(mBitmap, 0, 0, null); //繪製mBitmap 這是一個可變的bitmap,通過mCanvas繪製,首先繪製了mCoverBitmap drawPath(); } private void drawPath() { //使用該mode:dst和src相交後, 只保留dst,且除去相交的部份 mOuterPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); mCanvas.drawPath(mPath, mOuterPaint); }}
Paint.Join 連續畫筆銜接時
MITER 在外邊緣以一個銳角串連
ROUND 以圓弧
BEVEL 以直線
Paint.Cap 指定對於 線和路徑(lines and paths) 的開始和結束點的處理方式
BUTT ends with the path 不超越它
ROUND with the center at the end of the path 半圓
SQUARE with the center at the end of the path 方形
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
Android 自訂View 實現刮刮卡效果