最近公司有个新需求,让实现刮墙效果,说白了,就是刮刮乐,只是我们项目里面涉及的比较深,不是简单的添加一个图层,它包括底图,中间层,以及上面的刮墙图层,在网上找了好久,都木有合适的demo,后来拿来一个刮刮乐的例子,自己修改了一下。感谢不相识的朋友,放心哈,demo小女子已经修改过了
public class ScrapeWallView extends View {
private Context context = null; // 上下文
private int prizeNum; // 中奖金额
private Canvas topCanvas = null; // 涂层画板
private Bitmap topBitmap = null; // 涂层位图
private Path path = new Path(); // 画笔路径
private Paint paint = null; // 手指画笔
private int x = 0; // 当前触点X坐标
private int y = 0; // 当前触点Y坐标
private boolean showPrizeMsg = false; // 是否显示中奖信息
private int showMsgTime = 0; // 为避免重复提示,需要对提示进行计数
private boolean readyToPlay = false; // 是否可以开始玩
/**
* 构造函数
* @param context 上下文
**/
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public ScrapeWallView(Context context, int prizeNum) {
super(context);
// 内部对象赋值
prizeNum = prizeNum;
context = context;
// 试图初始化
InitView();
}
/**
* 初始化视图 */
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
private void InitView(){
// 设置视图背景图片
SetBackgroundImageForView();
// 设置表层涂层
SetCoverage();
// 初始化手指画笔
paint = GetFingerPaint();
// 设置变量
readyToPlay = true;
}
/**
* 清除剩余灰色涂层
*/
private void ClearCoverage(){
// 将涂层位图颜色设置为透明
topBitmap.eraseColor(0);
// 重绘
postInvalidate();
}
/**
* 视图试图绘制方法
*/
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
// 将path绘制到topBitmap涂层上
topCanvas.drawPath(path, paint);
// 将重绘后的topBitmap涂层绘制到View得画板中显示
canvas.drawBitmap(topBitmap, 0, 0, null);
}
/**
* 滑动触摸事件*/
@Override
public boolean onTouchEvent(MotionEvent event) {
// 如果没有初始化完成,不响应触摸事件
if (!readyToPlay)
return true;
int currX = (int) event.getX();
int currY = (int) event.getY();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:{
path.reset();
x = currX;
y = currY;
path.moveTo(x, y);
break;
}
case MotionEvent.ACTION_MOVE:{
// 二次贝塞尔,实现平滑曲线;previousX, previousY为操作点,cX, cY为终点
path.quadTo(x, y, currX, currY);
x = currX;
y = currY;
// 重绘View,再非UI线程中调用
postInvalidate();
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:{
path.reset();
ClearCoverage();
showPrizeMsg = true;
break;
}
}
return true; // 事件执行完毕
}
/**
* 设置涂层
*/
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
private void SetCoverage(){
// 等面积位图
topBitmap = Bitmap.createBitmap(1000, 800, Bitmap.Config.ARGB_8888);
Resources res = getResources();
// 将涂层位图载入到涂层画板
topCanvas = new Canvas(topBitmap);
Drawable drawable = getResources().getDrawable(R.drawable.wall_water_icon);
drawable.setBounds(50, 50, 950, 550);
drawable.draw(topCanvas);
// 设置涂层颜色
// 添加提示文字到涂层
Paint paint = new Paint();
paint.setTextSize(60);
paint.setColor(Color.DKGRAY);
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
paint.setAntiAlias(true);
topCanvas.drawText(getResources().getString(R.string.try_day_strg), 300, 330, paint);
}
/**
* 设置试图的背景图片
*/
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
private void SetBackgroundImageForView(){
// 设置视图背景图片
Resources res = getResources();
Bitmap bitmapw = Bitmap.createBitmap(1000, 800, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmapw);
// 将中奖图标绘制到画板中
Drawable drawable = LayoutToDrawable(R.layout.water_scrap_rlyt);
drawable.setBounds(0, 0, 1000, 800);
drawable.draw(canvas);
// 实例化可绘制位图,并绘制为视图的背景图
BitmapDrawable bd = new BitmapDrawable(getResources(), bitmapw);
setBackground(bd);
}
public Drawable LayoutToDrawable( int layout_id ){
LayoutInflater inflator = LayoutInflater.from(getContext());
View viewHelp = inflator.inflate(/*R.layout.test */ layout_id, null);
Bitmap snapshot = convertViewToBitmap(viewHelp);
Drawable drawable = (Drawable)new BitmapDrawable(snapshot);
return drawable;
}
public static Bitmap convertViewToBitmap(View view){
view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
return bitmap;
}
/**
* 初始化手指画笔
* @return 画笔
*/
private Paint GetFingerPaint(){
Paint paint = new Paint();
// 初始化画笔
paint.setFlags(Paint.ANTI_ALIAS_FLAG); // 消除锯齿
paint.setAntiAlias(true); // 设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢
paint.setDither(true); // 设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
paint.setStyle(Paint.Style.STROKE); // 画笔样式
paint.setStrokeWidth(80); // 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度
paint.setStrokeCap(Paint.Cap.ROUND); // 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式
paint.setStrokeJoin(Paint.Join.ROUND); // 结合处的样子
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); // 设置图形重叠时的处理方式
paint.setAlpha(0); // 设置绘制图形的透明度
return paint;
}
}