基于Android自定义控件实现刮刮乐效果
程序员文章站
2023-12-16 15:04:58
只是简单的实现了效果,界面没怎么做优化,不过那都是次要的啦!!相信大家都迫不及待的想看效果图了吧,
其中主要的彩票视图类和橡皮擦类都是通过代码的方式构建视...
只是简单的实现了效果,界面没怎么做优化,不过那都是次要的啦!!相信大家都迫不及待的想看效果图了吧,
其中主要的彩票视图类和橡皮擦类都是通过代码的方式构建视图,布局文件就一个主activity_main
上代码!!
主activity:
package com.guaguale; import android.app.activity; import android.os.bundle; import android.view.menu; import android.view.view; import android.view.view.onclicklistener; import android.view.viewgroup.layoutparams; import android.widget.button; import android.widget.relativelayout; /** * 主activity * * @author haozai * */ public class mainactivity extends activity { relativelayout container; button btn; erinieshow erinieshow; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); container = (relativelayout) findviewbyid(r.id.container); btn = (button) findviewbyid(r.id.enterbtn); btn.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { // todo auto-generated method stub showenrie(); } }); } private void showenrie() { // todo auto-generated method stub // 移除所有子元素 container.removeallviews(); // 产生一个彩票 int level = getlevel(); erinieshow = new erinieshow(this, level); container.addview(erinieshow, new layoutparams(-2, -2)); } /** * 获取奖励等级 * * @return */ private int getlevel() { // todo auto-generated method stub double d = math.random() * 100; if (d < 50) { return 3; } if (d < 90) { return 2; } return 1; } @override public boolean oncreateoptionsmenu(menu menu) { // inflate the menu; this adds items to the action bar if it is present. getmenuinflater().inflate(r.menu.main, menu); return true; } } 因为彩票视图相对复杂,所以通过自定义控件的方式,构造了一个彩票视图 package com.guaguale; import android.content.context; import android.graphics.color; import android.view.gravity; import android.view.view; import android.widget.button; import android.widget.relativelayout; /** * 彩票视图类 * * @author haozai * */ public class erinieshow extends relativelayout { int level; context mcontext; relativelayout rubberbg;// 最底层奖励等级 rubbershow mrubbershow;// 橡皮擦 button mbutton; int rubberbgid = 10001; int mbuttonid = 10002; public erinieshow(context context, int level) { super(context); // todo auto-generated constructor stub this.mcontext = context; this.level = level; getelement();// 得到子元素 setelementlp();// 设置布局参数 // 初始化彩票了 setelementstyle(); // 设置橡皮檫了 setelement(); } private void setelement() { // 第一步在彩票上面画一个图层 mrubbershow.beginrubber(color.parsecolor("#d3d3d3"), 30, 10); } private void setelementstyle() { switch (level) { case 1: rubberbg.setbackgroundresource(r.drawable.ic_launcher); break; case 2: rubberbg.setbackgroundresource(r.drawable.ic_launcher); break; case 3: rubberbg.setbackgroundresource(r.drawable.ic_launcher); break; default: break; } } /** * 给布局的子元素设置布局参数 */ private void setelementlp() { // todo auto-generated method stub relativelayout.layoutparams rubber_bg_lp = new relativelayout.layoutparams( 350, 80); rubberbg.setlayoutparams(rubber_bg_lp); mrubbershow.setlayoutparams(rubber_bg_lp); // rubber_bg_lp正下方 relativelayout.layoutparams rubber_btn_lp = new relativelayout.layoutparams( -2, -2); rubber_btn_lp.addrule(relativelayout.center_horizontal); rubber_btn_lp.addrule(relativelayout.below, rubberbgid); mbutton.setlayoutparams(rubber_btn_lp); mbutton.setclickable(false); } /** * 获取布局的子元素 */ private void getelement() { // todo auto-generated method stub rubberbg = new relativelayout(mcontext);// 得到彩票 mrubbershow = new rubbershow(mcontext, level);// 得到橡皮擦 mbutton = new button(mcontext); rubberbg.setid(rubberbgid); mbutton.setid(mbuttonid); mbutton.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { // todo auto-generated method stub } }); rubberbg.addview(mrubbershow); addview(rubberbg); addview(mbutton); } } 橡皮檫类,用于将中奖信息上面的临时画布去掉 package com.guaguale; import android.content.context; import android.graphics.bitmap; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; import android.graphics.bitmap.config; import android.graphics.paint.style; import android.graphics.path; import android.graphics.porterduff; import android.graphics.porterduffxfermode; import android.util.log; import android.view.motionevent; import android.view.view; import android.view.viewgroup.layoutparams; /** * 橡皮擦类 * * @author haozai * */ public class rubbershow extends view { private float touch_to_erance;// 填充的最小距离,这个值越小画出来的曲线越柔和 private bitmap bitmap; private canvas canvas;// 临时画布 private paint paint;// 画笔 private path mpath;// 鼠标的运行路径 private float mx, my;// 坐标 private boolean isdraw = false; public rubbershow(context context, int level) { super(context); // todo auto-generated constructor stub } @override protected void ondraw(canvas mcanvas) { // todo auto-generated method stub super.ondraw(mcanvas); if (isdraw) { log.i("tag", "111"); mcanvas.drawpath(mpath, paint); mcanvas.drawbitmap(bitmap, 0, 0, null);// 从起点开始画 } } @override public boolean ontouchevent(motionevent event) { if (!isdraw) { return true; } switch (event.getaction()) { case motionevent.action_down: 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 touchup(float x, float y) { // 画出路线 mpath.lineto(x, y); canvas.drawpath(mpath, paint); mpath.reset(); } private void touchmove(float x, float y) { float dx = math.abs(x - mx); float dy = math.abs(y - my); // 两点之间的距离大于touch_to_erance,就生成贝瑟尔曲线 if (dx >= touch_to_erance || dy >= touch_to_erance) { // 用贝瑟尔实现平滑的曲线 // mpath.lineto(dx, dy); mpath.quadto(mx, my, (x + mx) / 2, (y + my) / 2); mx = x; my = y; } } private void touchdown(float x, float y) { mpath.reset();// 重置路径 mpath.moveto(x, y); mx = x; my = y; } /** * @param bgcolor * 覆盖的背景颜色 * @param paintstrokewidth * 橡皮擦宽度 * @param touchtolerance * 填充距离 */ public void beginrubber(final int bgcolor, final int paintstrokewidth, float touchtolerance) { touch_to_erance = touchtolerance; paint = new paint(); // 画笔划过的痕迹变为透明 paint.setcolor(color.black);// 此处不能为透明 paint.setxfermode(new porterduffxfermode(porterduff.mode.dst_out)); paint.setantialias(true);// 变为光滑 paint.setstyle(style.stroke);// 空心和实心 paint.setstrokejoin(paint.join.round);// 前面圆角 paint.setstrokecap(paint.cap.round);// 后圆角 paint.setstrokewidth(paintstrokewidth);// 画笔宽度 // 覆盖 layoutparams layoutparams = getlayoutparams(); int height = layoutparams.height; int width = layoutparams.width; // if(layoutparams.height ==layoutparams.match_parent){ // // }else{ // // } // 记录痕迹 mpath = new path(); bitmap = bitmap.createbitmap(width, height, config.argb_4444);// 4444占内存更少 canvas = new canvas(bitmap); canvas.drawcolor(bgcolor); isdraw = true; } }
以上代码附有注释,有哪里不明白的地方欢迎大家提出宝贵意见,谢谢大家一直以来对网站的支持。