主要思想:
将一个view设计成多层:背景层,含中奖信息等;
遮盖层,用于刮奖,使用关联一个bitmap的canvas
在该bitmap上,使用它的canvas.drawpath的api来处理 手势滑动(类似刮奖的动作)
使用paint.setxfermode 来进行消除手势滑动区域
public class guaview extends view {
private bitmap mbitmap; //遮盖的图层
private canvas mcanvas; //绘制遮盖图层
private paint mouterpaint;
private path mpath;
private float mlastx;
private float mlasty;
private bitmap mcoverbitmap; //遮盖图
private int mwidth, mheight;
private paint minnerpaint;
private string minfo;
public guaview(context context) {
this(context, null);
}
public guaview(context context, attributeset attrs) {
super(context, attrs);
init();
}
private void init() {
mpath = new path();
mouterpaint = new paint();
minnerpaint = new paint();
mcoverbitmap = bitmapfactory.decoderesource(getresources(), r.drawable.fg_guaguaka);
minfo = "¥ 5 0 0";
}
@override
protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
super.onmeasure(widthmeasurespec, heightmeasurespec);
mwidth = mcoverbitmap.getwidth();
mheight = mcoverbitmap.getheight();
setmeasureddimension(mwidth, mheight);
mbitmap = bitmap.createbitmap(mwidth, mheight, bitmap.config.argb_8888);
mcanvas = new canvas(mbitmap);
mcanvas.drawbitmap(mcoverbitmap, 0, 0, null);
setouterpaint();
setinnerpaint();
}
private void setinnerpaint() {
minnerpaint.setcolor(color.red);
minnerpaint.setstyle(paint.style.stroke);
minnerpaint.setstrokecap(paint.cap.round);
minnerpaint.setstrokejoin(paint.join.round);
minnerpaint.setantialias(true);
minnerpaint.setdither(true); //防抖
minnerpaint.setstrokewidth(5);
minnerpaint.settextsize(100);
minnerpaint.settextalign(paint.align.center);
}
private void setouterpaint() {
mouterpaint.setcolor(color.green);
mouterpaint.setstyle(paint.style.stroke);
mouterpaint.setstrokecap(paint.cap.round);
mouterpaint.setstrokejoin(paint.join.round);
mouterpaint.setantialias(true);
mouterpaint.setdither(true); //防抖
mouterpaint.setstrokewidth(20);
}
@override //path
public boolean ontouchevent(motionevent event) {
float x = event.getx();
float y = event.gety();
switch (event.getaction()) {
case motionevent.action_down:
mlastx = x;
mlasty = y;
mpath.moveto(x, y);
break;
case motionevent.action_move:
float deltax = math.abs(x - mlastx);
float deltay = math.abs(y - mlasty);
if (deltax > 5 || deltay > 5) {
mpath.lineto(x, y);
}
mlastx = x;
mlasty = y;
break;
case motionevent.action_up:
break;
}
invalidate();//调用ondraw
return true;
}
@override
protected void ondraw(canvas canvas) {
super.ondraw(canvas);
canvas.drawcolor(color.parsecolor("#bbbbbb")); //背景底色 灰色
canvas.drawtext(minfo, mwidth / 2, mheight / 4 * 3, minnerpaint); //绘制文本
canvas.drawbitmap(mbitmap, 0, 0, null); //绘制mbitmap 这是一个可变的bitmap,通过mcanvas绘制,首先绘制了mcoverbitmap
drawpath();
}
private void drawpath() {
//使用该mode:dst和src相交后, 只保留dst,且除去相交的部份
mouterpaint.setxfermode(new porterduffxfermode(porterduff.mode.dst_out));
mcanvas.drawpath(mpath, mouterpaint);
}
}
paint.join 连续画笔衔接时:
miter 在外边缘以一个锐角连接
round 以圆弧
bevel 以直线
paint.cap 指定对于 线和路径(lines and paths) 的开始和结束点的处理方式:
butt ends with the path 不超越它
round with the center at the end of the path 半圆
square with the center at the end of the path 方形
更多android app中实现简单的刮刮卡抽奖效果的实例详解。