Android实现**"刮刮乐"效果
- 在一些应用,比如支付宝、天猫app我们经常能够看到一些刮奖的功能效果,通过用户手指滑动模拟出"刮刮乐"刮奖的视觉效果,让用户有一种刮**时候那种“爽”的感觉。
我们接下来就来用代码模拟出简配版“刮刮乐”效果,直接看效果图先
中了40W??(YY下) 是不是跟外面**店的刮刮乐有点相似。其实实现这个效果很简单,简单到你觉得不可思议~
1.首先我们创建一个类(TicketView)让其继承View,然后实现父类构造方法,代码就不贴了。
2.接下来我们要说明一个类BitmapShader ,该类是实现该效果的重点。BitmapShader继承于Shader,其实在上面文章仿华为手机管家“一键优化”Loading加载框 已经有简单提及过该类,Shader中文翻译着色器,其实就是给View进行绘制色彩变化的工具(你可以这么理解。。。)
看一下BitmapShapder的构造器
/**
* Call this to create a new shader that will draw with a bitmap.
*
* @param bitmap The bitmap to use inside the shader
* @param tileX The tiling mode for x to draw the bitmap in.
* @param tileY The tiling mode for y to draw the bitmap in.
*/
public BitmapShader(@NonNull Bitmap bitmap, @NonNull TileMode tileX, @NonNull TileMode tileY) {
this(bitmap, tileX.nativeInt, tileY.nativeInt);
}
我们先写个demo看下效果先。首先我们申明一个Paint画笔
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(30);
mPaint.setStrokeCap(Paint.Cap.ROUND);
然后声明一个Bitmap对象,找个背景图
调用画笔setShader将创建的BitmapShader设置进去
bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ticket);
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);
mPaint.setShader(shader);
- 在onDraw方法里面写几个文字
mPaint.setTextSize(180);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawText("看到了里面", 100, 500, mPaint);
运行后效果
我们看到了文字下面是居然是加载的那张bitmap。这个Paint似乎能够看穿一切~
BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)看下后面的那两个参数。
Shader.TileMode顾名思义肯定是一种模式,到这里就可以理解为是一种显示模式,进入这个类,我们会发现一共有 CLAMP, REPEAT, MIRROR三种显示模式。方法中的第一个Shader.TileMode是X轴的显示模式,第二个是Y轴上的显示模式。
/**
* replicate the edge color if the shader draws outside of its
* original bounds
*/
CLAMP (0),
/**
* repeat the shader's image horizontally and vertically
*/
REPEAT (1),
/**
* repeat the shader's image horizontally and vertically, alternating
* mirror images so that adjacent images always seam
*/
MIRROR (2);
看到上面的效果,我估计很多人对“刮刮乐”效果的实现方法已经很清楚了。是的,我们可以直接使用Path,根据手指滑动来绘制path,从而达到模拟“刮出”的效果,直接看代码~ (初始化代码跟上面是一致的)
这里我们用到贝塞尔曲线来绘制手指滑动轨迹,已达到顺滑的目的
private Path path = new Path();
//重写onTouchEvent
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
float x = event.getX();
float y = event.getY();
mX = x;
mY = y;
path.moveTo(x, y);
break;
case MotionEvent.ACTION_MOVE:
float x1 = event.getX();
float y1 = event.getY();
float preX = mX;
float preY = mY;
float dx = Math.abs(x1 - preX);
float dy = Math.abs(y1 - preY);
if (dx >= offset || dy >= offset) {
// 贝塞尔曲线的控制点为起点和终点的中点
float cX = (x1 + preX) / 2;
float cY = (y1 + preY) / 2;
path.quadTo(preX, preY, cX, cY);
mX = x1;
mY = y1;
}
}
invalidate();
return true;
}
在onDraw方法里面将path绘制出来
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(path,mPaint);
}
为了覆盖颜色更加逼真,将其设置为灰色
canvas.drawColor(Color.GRAY);
就能显示是上面的"刮刮乐"效果了~是不是很简单- -||