Android实现刮刮乐示例分析
程序员文章站
2024-03-03 18:46:40
微信公众号有很多都做刮刮乐的活动,本文就实现了刮刮乐的效果,具体代码如下:
首先要做一个类似橡皮擦的东西吧,然后才能把纸上的笔迹擦除
/**...
微信公众号有很多都做刮刮乐的活动,本文就实现了刮刮乐的效果,具体代码如下:
首先要做一个类似橡皮擦的东西吧,然后才能把纸上的笔迹擦除
/** * filename: splashactivity.java * * @desc 橡皮擦功能,类似刮刮乐效果 * @author htp * @date 20140311 * @version 1.00 */ public class text_rubbler extends textview { private float touch_tolerance; // 填充距离,使线条更自然,柔和,值越小,越柔和。 // private final int bgcolor; // 位图 private bitmap mbitmap; // 画布 private canvas mcanvas; // 画笔 private paint mpaint; private path mpath; private float mx, my; private boolean isdraw = false; public text_rubbler(context context) { /** * @param context 上下文 */ super(context); } public text_rubbler(context context, attributeset attrs, int defstyle) { super(context, attrs, defstyle); // bgcolor = // attrs.getattributeintvalue("http://schemas.android.com/apk/res/android", // "textcolor", 0xffffff); // system.out.println("color:"+bgcolor); } public text_rubbler(context context, attributeset attrs) { super(context, attrs); // bgcolor = // attrs.getattributeintvalue("http://schemas.android.com/apk/res/android", // "textcolor", 0xffffff); // system.out.println(bgcolor); // system.out.println(attrs.getattributevalue("http://schemas.android.com/apk/res/android", // "layout_width")); } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); if (isdraw) { mcanvas.drawpath(mpath, mpaint); // mcanvas.drawpoint(mx, my, mpaint); canvas.drawbitmap(mbitmap, 0, 0, null); } } /** * 开启檫除功能 * * @param bgcolor * 覆盖的背景颜色 * @param paintstrokewidth * 触点(橡皮)宽度 * @param touchtolerance * 填充距离,值越小,越柔和。 */ public void beginrubbler(final int bgcolor, final int paintstrokewidth, float touchtolerance) { touch_tolerance = touchtolerance; // 设置画笔 mpaint = new paint(); // mpaint.setalpha(0); // 画笔划过的痕迹就变成透明色了 mpaint.setcolor(color.black); // 此处不能为透明色 mpaint.setxfermode(new porterduffxfermode(porterduff.mode.dst_out)); // 或者 // mpaint.setalpha(0); // mpaint.setxfermode(new porterduffxfermode(porterduff.mode.dst_in)); mpaint.setantialias(true); mpaint.setdither(true); mpaint.setstyle(paint.style.stroke); mpaint.setstrokejoin(paint.join.round); // 前圆角 mpaint.setstrokecap(paint.cap.round); // 后圆角 mpaint.setstrokewidth(paintstrokewidth); // 笔宽 // 痕迹 mpath = new path(); ; // 覆盖 // if (getlayoutparams().width == layoutparams.fill_parent) { // // } mbitmap = bitmap.createbitmap(getlayoutparams().width, getlayoutparams().height, config.argb_8888); mcanvas = new canvas(mbitmap); mcanvas.drawcolor(bgcolor); isdraw = true; } @override public boolean ontouchevent(motionevent event) { if (!isdraw) { return true; } switch (event.getaction()) { case motionevent.action_down: // 触点按下 // touchdown(event.getrawx(),event.getrawy()); touchdown(event.getx(), event.gety()); invalidate(); break; case motionevent.action_move: // 触点移动 touchmove(event.getx(), event.gety()); invalidate(); break; case motionevent.action_up: // 触点弹起 touchup(event.getx(), event.gety()); invalidate(); break; default: break; } return true; } private void touchdown(float x, float y) { mpath.reset(); mpath.moveto(x, y); mx = x; my = y; } private void touchmove(float x, float y) { float dx = math.abs(x - mx); float dy = math.abs(y - my); if (dx >= touch_tolerance || dy >= touch_tolerance) { mpath.quadto(mx, my, (x + mx) / 2, (y + my) / 2); mx = x; my = y; } } private void touchup(float x, float y) { mpath.lineto(x, y); mcanvas.drawpath(mpath, mpaint); mpath.reset(); } }
接下来就是使用橡皮檫擦除了
/** * filename: rubbleract.java * @desc 该类通过调用text_rubbler这个类将在activity上显示一片刮一刮的区域,可以出发触摸事件 * @author htp * @date 20140312 * @version 1.00 */ public class rubbleract extends activity { // 刮开后文字显示 private textview tv_rubbler; // 得到刮一刮的内容 private sentence msentence; // 下一张 private textview tv_next; @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); // setcontentview(new rubble(this,"谢谢惠顾",new rect(100, 200, // 300,250),2,1f,14)); // ///////////////////////////////////////// setcontentview(r.layout.rubbler); // 设置的颜色必须要有透明度。 ((text_rubbler) findviewbyid(r.id.rubbler)).beginrubbler(0xffffffff, 20, 1f);// 设置橡皮擦的宽度等 msentence = new sentence(); // 随机初始化文字 tv_rubbler = (textview) findviewbyid(r.id.rubbler); string str = msentence.getsentence(); tv_rubbler.settext(str); tv_next = (textview) findviewbyid(r.id.tv_next); // 点击下一步 tv_next.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { // todo auto-generated method stub string str = msentence.getsentence(); tv_rubbler.settext(str); ((text_rubbler) findviewbyid(r.id.rubbler))// 初始化状态 .beginrubbler(0xffffffff, 20, 1f); } }); } class rubble extends view { private final int paint_stroke_width; private final float touch_tolerance; // 填充距离,使线条更自然,柔和,值越小,越柔和。 private final int text_size; private bitmap mbitmap; // 画布 private canvas mcanvas; // 画笔 private paint mpaint; private path mpath; private float mx, my; private final int x, y, w, h; private final rect touchrect; public rubble(context context, string bgtext, rect rect, int paintstrokewidth, float touchtolerance, int textsize) { super(context); setfocusable(true); touchrect = rect; w = rect.right - rect.left; h = rect.bottom - rect.top; x = rect.left; y = rect.top; text_size = textsize; paint_stroke_width = paintstrokewidth; touch_tolerance = touchtolerance; setbackground(touchrect, bgtext); initdrowtools(); } private void setbackground(rect rect, string bgtext) { displaymetrics dm = new displaymetrics(); dm = this.getresources().getdisplaymetrics(); bitmap bitmap = bitmap.createbitmap(dm.widthpixels, dm.heightpixels, config.argb_8888); canvas canvas = new canvas(bitmap); paint paint = new paint(); paint.setcolor(0x88000000); // paint.setstyle(style.stroke); // paint.settextalign(align.center); paint.settextsize(text_size); // paint.settextscalex(1.5f); canvas.drawcolor(color.white); // 画字的坐标不好控制 int x = rect.left + (rect.right - rect.left - bgtext.length() * text_size) / 2; int y = rect.top + (rect.bottom - rect.top - text_size) / 2; // int y = 218+25; canvas.drawtext(bgtext, x, y, paint); drawable drawable = new bitmapdrawable(bitmap); setbackgrounddrawable(drawable); } private void initdrowtools() { // 设置画笔 mpaint = new paint(); // mpaint.setalpha(0); // 画笔划过的痕迹就变成透明色了 mpaint.setcolor(color.black); // 此处不能为透明色 mpaint.setxfermode(new porterduffxfermode(porterduff.mode.dst_out)); // 或者 // mpaint.setalpha(0); // mpaint.setxfermode(new // porterduffxfermode(porterduff.mode.dst_in)); mpaint.setantialias(true); mpaint.setdither(true); mpaint.setstyle(paint.style.stroke); mpaint.setstrokejoin(paint.join.round); // 前圆角 mpaint.setstrokecap(paint.cap.round); // 后圆角 mpaint.setstrokewidth(paint_stroke_width); // 笔宽 // 痕迹 mpath = new path(); ; // 覆盖 mbitmap = bitmap.createbitmap(w, h, config.argb_8888); mcanvas = new canvas(mbitmap); mcanvas.drawcolor(0x88000000); } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); mcanvas.drawpath(mpath, mpaint); // mcanvas.drawpoint(mx, my, mpaint); canvas.drawbitmap(mbitmap, x, y, null); } @override public boolean ontouchevent(motionevent event) { system.out.print("x--" + event.getx()); system.out.println("y--" + event.gety()); if (!touchrect.contains((int) event.getx(), (int) event.gety())) { return false; } switch (event.getaction()) { // 触点按下 case motionevent.action_down: { touchdown(event.getrawx(), event.getrawy()); touchdown(event.getx() - touchrect.left, event.gety() - touchrect.top); invalidate(); break; } case motionevent.action_move: // 触点移动 touchmove(event.getx() - touchrect.left, event.gety() - touchrect.top); invalidate(); break; case motionevent.action_up: // 触点弹起 touchup(event.getx() - touchrect.left, event.gety() - touchrect.top); invalidate(); break; default: break; } return true; } private void touchdown(float x, float y) { mpath.reset(); mpath.moveto(x, y); mx = x; my = y; } private void touchmove(float x, float y) { float dx = math.abs(x - mx); float dy = math.abs(y - my); if (dx >= touch_tolerance || dy >= touch_tolerance) { mpath.quadto(mx, my, (x + mx) / 2, (y + my) / 2); mx = x; my = y; } } private void touchup(float x, float y) { mpath.lineto(x, y); mcanvas.drawpath(mpath, mpaint); mpath.reset(); } } /** * 键盘事件,当按下back键的时候询问是否再按一次退出程序 */ // 退出时间 private long exittime = 0; @override public boolean onkeydown(int keycode, keyevent event) { if (keycode == keyevent.keycode_back && event.getaction() == keyevent.action_down) { if ((system.currenttimemillis() - exittime) > 2000) { toast.maketext(getapplicationcontext(), "再按一次退出程序", toast.length_short).show(); exittime = system.currenttimemillis(); } else { finish(); system.exit(0); } return true; } return super.onkeydown(keycode, event); } }
实现效果如下:
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
上一篇: java自加和自减运算过程