制作简单刮刮乐View

一、引言

本篇刮刮乐,基于PorterDuffXfermode实现。

Mode.CLEAR  
Mode.SRC  
Mode.DST  
Mode.SRC_OVER  
Mode.DST_OVER  
Mode.SRC_IN  
Mode.DST_IN  
Mode.SRC_OUT  
Mode.DST_OUT  
Mode.SRC_ATOP  
Mode.DST_ATOP  
Mode.XOR  
Mode.DARKEN  
Mode.LIGHTEN  
Mode.MULTIPLY  
Mode.SCREEN  
Mode.OVERLAY  
Mode.ADD  

下面引用网上一张图来显示,google 提供的不同,经与源码对比是因为src 图绘画的位置不同而导致。



效果图:



源码如下:

package com.example.hoperun.defineview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by xuze on 17-8-21.
 * 简单刮刮乐的实现
 *
 */

public class GuagualeView extends View {
    private Paint mPaint = null;
    private Bitmap bitmapDst = null;
    private Bitmap bitmapSrc = null;
    private Bitmap bitmapResult = null;
    private Path mPath = null;
    private float mPreX,mPreY;


    public GuagualeView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        mPaint = new Paint();
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(45);                 //设置画笔
        mPath = new Path();
        bitmapResult = BitmapFactory.decodeResource(getResources(), R.drawable.first);
        bitmapDst = BitmapFactory.decodeResource(getResources(), R.drawable.guaguale);
        bitmapSrc = Bitmap.createBitmap(bitmapDst.getWidth(), bitmapDst.getHeight(), Bitmap.Config.ARGB_8888);


    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //1. 先画结果, 中奖图片
        canvas.drawBitmap(bitmapResult, 0, 200, mPaint);

        int layId = canvas.saveLayer(0, 0, bitmapDst.getWidth(), bitmapDst.getHeight(), null, Canvas.ALL_SAVE_FLAG);

        Canvas mCanvas = new Canvas(bitmapSrc);
        mCanvas.drawPath(mPath, mPaint);

        //2. 画目标
        canvas.drawBitmap(bitmapDst, 0, 0, mPaint);

//        //3. 设置
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
        canvas.drawBitmap(bitmapSrc, 0, 0, mPaint);

        mPaint.setXfermode(null);

        canvas.restoreToCount(layId);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //绘制指纹path
        switch(event.getAction()){
            case MotionEvent.ACTION_DOWN:
                mPath.moveTo(event.getX(), event.getY());
                mPreX = event.getX();
                mPreY = event.getY();
                return true;
            case MotionEvent.ACTION_MOVE:
//                mPath.lineTo(event.getX(), event.getY());
                float x = (mPreX + event.getX()) / 2;
                float y = (mPreY + event.getY()) / 2;
                mPath.quadTo(mPreX, mPreY, x, y);
                mPreX = event.getX();
                mPreY = event.getY();

                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }
}



二、CODE解析

1. 构造方法:    创建画笔,路径,3个bitmap(1结果,2目标图,3源图)    结果的图片可以换成字符串等
        mPaint = new Paint();
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(45);
        mPath = new Path();
        bitmapResult = BitmapFactory.decodeResource(getResources(), R.drawable.first);
        bitmapDst = BitmapFactory.decodeResource(getResources(), R.drawable.guaguale);
        bitmapSrc = Bitmap.createBitmap(bitmapDst.getWidth(), bitmapDst.getHeight(

2. onDraw
@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //1. 先画结果, 中奖图片
        canvas.drawBitmap(bitmapResult, 0, 200, mPaint);

        int layId = canvas.saveLayer(0, 0, bitmapDst.getWidth(), bitmapDst.getHeight(), null, Canvas.ALL_SAVE_FLAG);
        //2. 将path与bitmap结合
        Canvas mCanvas = new Canvas(bitmapSrc);
        mCanvas.drawPath(mPath, mPaint);

        //3. 画目标
        canvas.drawBitmap(bitmapDst, 0, 0, mPaint);

        //4. 设置样式
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
        canvas.drawBitmap(bitmapSrc, 0, 0, mPaint);

        mPaint.setXfermode(null);

        canvas.restoreToCount(layId);

    }

3. 贝塞尔曲线绘制手触路径

@Override
    public boolean onTouchEvent(MotionEvent event) {
        //绘制指纹path
        switch(event.getAction()){
            case MotionEvent.ACTION_DOWN:
                mPath.moveTo(event.getX(), event.getY());      //path起点
                mPreX = event.getX();
                mPreY = event.getY();
                return true;
            case MotionEvent.ACTION_MOVE:
                float x = (mPreX + event.getX()) / 2;
                float y = (mPreY + event.getY()) / 2;
                mPath.quadTo(mPreX, mPreY, x, y);             //绘制贝塞尔曲线
                mPreX = event.getX();
                mPreY = event.getY();

                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }


猜你喜欢

转载自blog.csdn.net/weixin_39158738/article/details/77455282