欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

基于Android自定义控件实现刮刮乐效果

程序员文章站 2023-12-16 15:04:58
 只是简单的实现了效果,界面没怎么做优化,不过那都是次要的啦!!相信大家都迫不及待的想看效果图了吧, 其中主要的彩票视图类和橡皮擦类都是通过代码的方式构建视...

 只是简单的实现了效果,界面没怎么做优化,不过那都是次要的啦!!相信大家都迫不及待的想看效果图了吧,

基于Android自定义控件实现刮刮乐效果

其中主要的彩票视图类和橡皮擦类都是通过代码的方式构建视图,布局文件就一个主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;
}
}

以上代码附有注释,有哪里不明白的地方欢迎大家提出宝贵意见,谢谢大家一直以来对网站的支持。

上一篇:

下一篇: