【我的Android进阶之旅】自定义控件之刮刮卡效果

先附上妹子图一张

android刮刮卡效果原理讲解:

刮刮卡其实就是上面有个遮罩层,遮罩层会随着手指的滑动慢慢不可见,我们在内存中创建一块画布,让手指的滑动的区域和这块遮罩层的交集消失不可见即可。 我们这里让底部显示了一张妹子的图片,当然也可以是文字或者别的,底部背景是图片还是文字我们不需要关心,我们只需要关心的是这个遮罩层和手势滑动过的区域的交集处。

画笔有setXferMode方法,这个是进行图层混合用到的,请看下图:

我们看下DstIn 和DstOut :
进行混合时底部的图层为Dst,上层的为Src.在这里,遮罩层为Dst,手势走过的路径为Src.
我们看DstIn,代表取Dst中两者的交集部分显示。这个显然不符合。
我们再看Dstout,代表取Dst中两者的不相交部分显示。我们手势划过的部分与遮罩层相交(这块的遮罩层不显示),没滑到的地方就不相交,(这块的遮罩层显示)。这样正好符合我们的要求。

上代码:


/**
 * Time:2019/9/11
 * Author:Jimmy Wang
 * Email:wzy901213@163.com
 * Blog:https://blog.csdn.net/wzy901213
 * Description:
 */
public class GuaGuaKaView extends View {
    /**
     * 绘制线条的Paint,即用户手指绘制Path
     */
    private Paint mOutterPaint = new Paint();
    /**
     * 绘制遮罩层Paint
     */
    private  Paint mPaint = new Paint();
    /**
     * 记录用户绘制的Path
     */
    private Path mPath = new Path();
    /**
     * 美女背景图
     */
    private Bitmap mBitmap;
    /**
     * 遮罩层目标背景图
     */
    private Bitmap mDstBitmap;
    /**
     * 内存缓存的Canvas
     */
    Canvas mCanvas ;

    private int mLastX,mLastY;

    public GuaGuaKaView(Context context) {
        super(context);
    }

    public GuaGuaKaView(Context context,AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        mBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.beauty);
        mOutterPaint.setColor(Color.RED);
        mOutterPaint.setAntiAlias(true);
        mOutterPaint.setDither(true);
        mOutterPaint.setStyle(Paint.Style.STROKE);
        mOutterPaint.setStrokeJoin(Paint.Join.ROUND); // 圆角
        mOutterPaint.setStrokeCap(Paint.Cap.ROUND); // 圆角
        // 设置画笔宽度
        mOutterPaint.setStrokeWidth(50);
        mOutterPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mDstBitmap = Bitmap.createBitmap(getMeasuredWidth(),getMeasuredHeight() ,Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mDstBitmap);
        mCanvas.drawColor(Color.GRAY);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(mBitmap,0,0, mPaint);
        canvas.drawBitmap(mDstBitmap,0,0, mPaint);
        drawPath();
    }


    /**
     * 绘制线条
     */
    private void drawPath()
    {
        mCanvas.drawPath(mPath, mOutterPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        int action = event.getAction();
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (action)
        {
            case MotionEvent.ACTION_DOWN:
                mLastX = x;
                mLastY = y;
                mPath.moveTo(mLastX, mLastY);
                break;
            case MotionEvent.ACTION_MOVE:

                int dx = Math.abs(x - mLastX);
                int dy = Math.abs(y - mLastY);

                if (dx > 3 || dy > 3)
                    mPath.lineTo(x, y);

                mLastX = x;
                mLastY = y;
                break;
        }

        invalidate();
        return true;
    }
}

写在最后:

如果这里的遮盖层是妹子的衣服,然后背景是个没穿衣服的妹子,我们不停滑的话会怎样,真不敢想象

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值