Andriod: scratch card Effect
Thoughts:
Design a View into multiple layers, the inner layer (including the winning information) and the outer layer (used for prize scraping). The outer layer is associated with a Bitmap using Canvas, this associated Bitmap is used to handle gesture slide, similar to the prize-winning action.
Use paint. setXfermode to remove gesture sliding areas
Package com. jackie. guaguale; import android. content. context; import android. graphics. bitmap; import android. graphics. bitmapFactory; import android. graphics. canvas; import android. graphics. color; import android. graphics. paint; import android. graphics. path; import android. graphics. porterDuff; import android. graphics. porterduxfermode; import android. util. attributeSet; import android. view. motionEvent; import android. view. view;/*** Created by Administrator on 2015/7/29. */public class GuaView extends View {private Path mPath; private Paint mInnerPaint; // The Paint private Paint mOuterPaint layer of the inner layer; // The Paint private Bitmap mGuaBitmap layer of the outer layer; // Bitmap private Bitmap mOuterBitmap for processing the prize; // Bitmap private Canvas mCanvas; private int mWidth, mHeight; private float mLastX; private float mLastY; private String mText; public GuaView (Context context, AttributeSet attrs) {super (context, attrs); init () ;}private void init () {mPath = new Path (); mOuterPaint = new Paint (); mInnerPaint = new Paint (); // create an outer layer mOuterBitmap = BitmapFactory. decodeResource (getResources (), R. drawable. guaguaka ). copy (Bitmap. config. ARGB_8888, true); mText = ¥ 500;} @ Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {super. onMeasure (widthMeasureSpec, heightMeasureSpec); mWidth = mOuterBitmap. getWidth (); mHeight = mOuterBitmap. getHeight (); // create an inner layer mGuaBitmap = Bitmap. createBitmap (mWidth, mHeight, Bitmap. config. ARGB_8888); mCanvas = new Canvas (mGuaBitmap); mCanvas. drawBitmap (mOuterBitmap, 0, 0, null); // draw mOuterBitmap to mCanvas and associate it with mGuaBitmap 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); // anti-shake 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); // anti-shake 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 (); return true;} @ Override protected void onDraw (Canvas canvas) {super. onDraw (canvas); canvas. drawColor (Color. parseColor (# bbbbbb); // background gray canvas. drawText (mText, mWidth/2, mHeight/4*3, mInnerPaint); // draw the text canvas. drawBitmap (mGuaBitmap, 0, 0, null); // draw the outer Bitmap and display the mBitmap on the Interface drawPath ();} private void drawPath () {// use this mode: only dst is retained after dst and src are intersecting, and the intersection of some mOuterPaint is removed. setXfermode (new porterduxfermode (PorterDuff. mode. DST_OUT); mCanvas. drawPath (mPath, mOuterPaint );}}
As follows: