其实很简单就是ImageView先画蒙版,蒙版需要是本地的图片,这里画图片需要本地图的地址或者流 如果需要加载线上的图片,建议图片缓存流然后加载(当然只是纸上谈兵,有心的小伙伴可以试试) 这里在抬手的时候就进行加载网络图片了 public class MyCardView extends AppCompatImageView { private Paint mForePaint; private Bitmap mBitmap;//加载资源文件 private Canvas mForeCanvas;//前景图Canvas private Bitmap mForeBitmap;//前景图Bitmap private boolean isClear = false; private Path mPath = new Path(); private String overPath = "",backPath = ""; public MyCardView(Context context) { super(context); } public MyCardView(Context context, AttributeSet attrs) { super(context, attrs); } public MyCardView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void setImages(int width,int height,InputStream inputStream, String backPath){ this.overPath = overPath; this.backPath = backPath; mBitmap = BitmapFactory.decodeStream(inputStream); mForePaint = new Paint(); mForePaint.setAntiAlias(true); mForePaint.setAlpha(0); mForePaint.setStrokeCap(Paint.Cap.ROUND); mForePaint.setStrokeJoin(Paint.Join.ROUND); mForePaint.setStyle(Paint.Style.STROKE); mForePaint.setStrokeWidth(50); mForePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); mForeBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); mForeCanvas = new Canvas(mForeBitmap); mForeCanvas.drawBitmap(mBitmap, 0, 0, null); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (!isClear) { canvas.drawBitmap(mForeBitmap, 0, 0, null); }else { Glide.with(getContext()).load(backPath).into(this); } } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: mPath.moveTo(event.getX(), event.getY()); break; case MotionEvent.ACTION_MOVE: mPath.lineTo(event.getX(),event.getY()); break; case MotionEvent.ACTION_UP: isClear = true; postInvalidate(); break; } mForeCanvas.drawPath(mPath, mForePaint); invalidate(); return true; } }
这里是GitHub - Lichenwei-Dev/ScratchCardView: Android开发之自定义刮刮卡实现
这个大神实现的效果,是判断所挂面积判断是否显示
/** * 开启子线程计算被擦除的像素点 */ private Runnable mRunnable = new Runnable() { int[] pixels; @Override public void run() { int w = mForeBitmap.getWidth(); int h = mForeBitmap.getHeight(); float wipeArea = 0; float totalArea = w * h; pixels = new int[w * h]; /** * pixels 接收位图颜色值的数组 * offset 写入到pixels[]中的第一个像素索引值 * stride pixels[]中的行间距个数值(必须大于等于位图宽度)。可以为负数 * x 从位图中读取的第一个像素的x坐标值。 * y 从位图中读取的第一个像素的y坐标值 * width 从每一行中读取的像素宽度 * height 读取的行数 */ mForeBitmap.getPixels(pixels, 0, w, 0, 0, w, h); for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { int index = i + j * w; if (pixels[index] == 0) { wipeArea++; } } } if (wipeArea > 0 && totalArea > 0) { int percent = (int) (wipeArea * 100 / totalArea); if (percent > 50) { isClear = true; postInvalidate(); } } } };