您的位置:首页 > 移动开发 > Android开发

Android 刮刮卡原理

2015-12-01 00:16 295 查看

Android 刮刮卡原理

个人做个记录,无意从研发变成了产品,现在回头做做代码,练练生手。
只看刮的原理,很简单。需要知道的核心就1个:Paint.setXfermode。
基本原理:

一共分两层,如下图,上面一层用于刮,下面一层用于显示。演示代码为偷懒的方式用两个控件层叠,实际应该使用自定义控件绘制。
刮奖层在触摸时,使用Paint.setXfermode在刮奖层绘制,达到部分透明的目的。



动手:
1. 布局,就类似上图,两个控件层叠(实际请自行绘制自定义控件,如代码本来应该只有GuaGuaCard)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ScrollingActivity">

<TextView
android:layout_width="300dp"
android:layout_height="300dp"
android:gravity="center"
android:text="5000"
android:textSize="100dp" />

<com.mc.wiget.GuaGuaCard
android:layout_width="300dp"
android:layout_height="300dp" />

</FrameLayout>


2. 创建刮奖层自定义控件
刮奖层自定义控件的原理是,创建一个灰色的图片绘制到canvas,在触摸事件中不端的使用Path在图片上绘制“擦除区域”,实际是Xfermode的dst_out模式。
1)初始化绘制蒙层的画笔
/**
* 初始化画笔
*/
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); //导致擦除效果的核心
mPaint.setColor(Color.BLACK);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(40);
mPaint.setStyle(Paint.Style.STROKE);

mPath = new Path();
}


2)绘制好基本的蒙层
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//测量蒙层大小,并初始化
mFrontGround = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
//将蒙层绘制到刮奖区域
mFrontCanvas = new Canvas(mFrontGround);
mFrontCanvas.drawColor(Color.BLUE);
}


3) 在手指移动时绘制擦除区域
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
float x = 0;
float y = 0;

switch (action) {
//按下时移动擦除的起点到手指落下的坐标
case MotionEvent.ACTION_DOWN: {
x = event.getX();
y = event.getY();
mPath.moveTo(x, y);
break;
}
//移动时绘制直线,即擦除区域
case MotionEvent.ACTION_MOVE:
x = Math.abs(event.getX() - x);
y = Math.abs(event.getY() - y);
mPath.lineTo(x, y);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
default:
break;
}

//绘制
invalidate();
return true;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

//在刮奖区域上绘制擦除区域,因为用了xfermode,所以这块会是透明的
mFrontCanvas.drawPath(mPath, mPaint);

//将刮奖区域绘制到控件上展示
canvas.drawBitmap(mFrontGround, 0, 0, null);
}


这样基本就能够把刮奖层搞定,那后面的,要是一时想不清楚,可以尝试源码下载



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: