天天看点

刮刮乐实现android中刮墙效果

最近公司有个新需求,让实现刮墙效果,说白了,就是刮刮乐,只是我们项目里面涉及的比较深,不是简单的添加一个图层,它包括底图,中间层,以及上面的刮墙图层,在网上找了好久,都木有合适的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;
    }
}      

继续阅读