Android 实现九宫格抽奖功能
程序员文章站
2022-07-06 09:18:14
效果展示实现步骤1.生成抽奖矩形:其中每个矩形的宽高相同,长度为整个控件宽度的1/3。代码展示public class nineluckpan extends view { private paint...
效果展示
实现步骤
1.生成抽奖矩形:
其中每个矩形的宽高相同,长度为整个控件宽度的1/3。
代码展示
public class nineluckpan extends view { private paint mpaint; private arraylist<rectf> mrects;//存储矩形的集合 private float mstrokwidth = 5;//矩形的描边宽度 private int mrectsize;//矩形的宽和高(矩形为正方形) private int[] mitemcolor = {color.green, color.yellow};//矩形的颜色 public nineluckpan(context context) { this(context, null); } public nineluckpan(context context, @nullable attributeset attrs) { this(context, attrs, 0); } public nineluckpan(context context, @nullable attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); init(); } /** * 初始化数据 */ private void init() { mpaint = new paint(paint.anti_alias_flag); mpaint.setstyle(paint.style.fill); mpaint.setstrokewidth(mstrokwidth); mrects = new arraylist<>(); } @override protected void onsizechanged(int w, int h, int oldw, int oldh) { super.onsizechanged(w, h, oldw, oldh); mrectsize = math.min(w, h) / 3;//获取矩形的宽和高 mrects.clear();//当控件大小改变的时候清空数据 initrect();//重新加载矩形数据 } /** * 加载矩形数据 */ private void initrect() { //加载前三个矩形 for (int x = 0; x < 3; x++) { float left = x * mrectsize; float top = 0; float right = (x + 1) * mrectsize; float bottom = mrectsize; rectf rectf = new rectf(left, top, right, bottom); mrects.add(rectf); } //加载第四个 mrects.add(new rectf(getwidth() - mrectsize, mrectsize, getwidth(), mrectsize * 2)); //加载第五~七个 for (int y = 3; y > 0; y--) { float left = getwidth() - (4 - y) * mrectsize; float top = mrectsize * 2; float right = (y - 3) * mrectsize + getwidth(); float bottom = mrectsize * 3; rectf rectf = new rectf(left, top, right, bottom); mrects.add(rectf); } //加载第八个 mrects.add(new rectf(0, mrectsize, mrectsize, mrectsize * 2)); //加载第九个 mrects.add(new rectf(mrectsize, mrectsize, mrectsize * 2, mrectsize * 2)); } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); drawrects(canvas); } /** * 画矩形 * * @param canvas */ private void drawrects(canvas canvas) { for (int x = 0; x < mrects.size(); x++) { rectf rectf = mrects.get(x); if (x == 8) {//中心的矩形背景为白色 mpaint.setcolor(color.white); canvas.drawrect(rectf, mpaint); } else { mpaint.setcolor(mitemcolor[x % 2]); canvas.drawrect(rectf, mpaint); } } } }
效果展示
2.添加奖品图片:
我们在矩形的中心点画出图片,图片的宽高都为矩形宽高的1/2,其中矩形的中心点通过rectf.centerx()和rectf.centery()获取。
代码展示(为了方便只展示部分代码)
public class nineluckpan extends view { private int[] mimgs = {r.drawable.ic_df, r.drawable.ic_jt, r.drawable.ic_mf, r.drawable.ic_scjx, r.drawable.ic_scng, r.drawable.ic_thl, r.drawable.ic_x, r.drawable.ic_xc, r.drawable.ic_j}; @override protected void ondraw(canvas canvas) { super.ondraw(canvas); drawrects(canvas);//画矩形 drawimages(canvas);//画图片 } /** * 画图片 * * @param canvas */ private void drawimages(canvas canvas) { for (int x = 0; x < mrects.size(); x++) { rectf rectf = mrects.get(x); float left = rectf.centerx() - mrectsize / 4; float top = rectf.centery() - mrectsize / 4; canvas.drawbitmap(bitmap.createscaledbitmap(bitmapfactory.decoderesource(getresources(), mimgs[x]), mrectsize / 2, mrectsize / 2, false), left, top, null); } } }
效果展示
3.实现抽奖动画:
这里我们使用valueanimator使数字从0递增到我们的中奖位置比如3,然后改变递增所在的位置的矩形的背景以实现抽奖的效果,另外为了让用户感到逼真我们需要让抽奖色块多转几圈,同时我们需要将下一次的开始位置设为上一次的结束位置。
代码展示(为了方便只展示部分代码)
nineluckpan:
public class nineluckpan extends view { private int mrepeatcount = 3;//转的圈数 private int mlucknum = 3;//最终中奖位置 private int mposition = -1;//抽奖块的位置 private int mstartluckposition = 0;//开始抽奖的位置 /** * 画矩形 * @param canvas */ private void drawrects(canvas canvas) { for (int x = 0;x<mrects.size();x++){ rectf rectf = mrects.get(x); if(x == 8){ mpaint.setcolor(color.white); canvas.drawrect(rectf, mpaint); }else { mpaint.setcolor(mitemcolor[x%2]); if(mposition == x){ mpaint.setcolor(color.blue); } canvas.drawrect(rectf, mpaint); } } } public void setposition(int position){ mposition = position; invalidate(); } /** * 开始动画 */ public void startanim(){ valueanimator valueanimator = valueanimator.ofint(mstartluckposition, mrepeatcount * 8 + mlucknum).setduration(5000); valueanimator.addupdatelistener(new valueanimator.animatorupdatelistener() { @override public void onanimationupdate(valueanimator animation) { int position = (int) animation.getanimatedvalue(); setposition(position%8); } }); valueanimator.addlistener(new animatorlisteneradapter() { @override public void onanimationend(animator animation) { mstartluckposition = mlucknum; } }); valueanimator.start(); } }
activity:
public class mainactivity extends appcompatactivity { private nineluckpan luckpan; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); luckpan = (nineluckpan) findviewbyid(r.id.luckpan); luckpan.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { luckpan.startanim(); } }); } }
效果展示
虽然效果实现了但是我们发现好像点哪里都能启动动画,因此我们需要调整一下代码使只有点击中心的矩形才开始动画。
//(为了方便只展示部分代码) public class nineluckpan extends view { private boolean mclickstartflag = false;//是否点击中间矩形的标记 //这样需要我们将activity里的启动动画的逻辑删掉 @override public boolean ontouchevent(motionevent event) { if(event.getaction() == motionevent.action_down){ if(mrects.get(8).contains(event.getx(),event.gety())){ mclickstartflag = true; }else { mclickstartflag = false; } return true; } if(event.getaction() == motionevent.action_up){ if(mclickstartflag){ if(mrects.get(8).contains(event.getx(),event.gety())){ startanim();//判断只有手指落下和抬起都在中间的矩形内才开始抽奖 } mclickstartflag = false; } } return super.ontouchevent(event); } }
4.实现动态设置参数:
效果基本实现了,接下来就需要实现动态设置数据了。
代码展示(这里为了方便只展示部分代码)
public class nineluckpan extends view { private int mlucknum = 3;//最终中奖位置 private int [] mimgs = {r.drawable.ic_df,r.drawable.ic_jt,r.drawable.ic_mf,r.drawable.ic_scjx,r.drawable.ic_scng,r.drawable.ic_thl,r.drawable.ic_x,r.drawable.ic_xc,r.drawable.ic_j}; private string[] mluckstr = {"豆腐","鸡腿","米饭","卷心菜","南瓜","糖葫芦","大虾","香肠"};//这是抽奖的提示信息 public int getmlucknum() { return mlucknum; } public void setmlucknum(int mlucknum) { this.mlucknum = mlucknum; } public int[] getmimgs() { return mimgs; } public void setmimgs(int[] mimgs) { this.mimgs = mimgs; invalidate();//要注意设置完后要进行重绘 } public string[] getmluckstr() { return mluckstr; } public void setmluckstr(string[] mluckstr) { this.mluckstr = mluckstr; invalidate();;//要注意设置完后要进行重绘 } }
5.添加抽奖结果回调
这里需要在动画结束的回调里加入我们自定义的回调函数。
代码展示(这里为了方便只展示部分代码)
public class nineluckpan extends view { private onluckpananimendlistener onluckpananimendlistener; public onluckpananimendlistener getonluckpananimendlistener() { return onluckpananimendlistener; } public void setonluckpananimendlistener(onluckpananimendlistener onluckpananimendlistener) { this.onluckpananimendlistener = onluckpananimendlistener; } /** * 开始动画 */ private void startanim(){ valueanimator valueanimator = valueanimator.ofint(mstartluckposition, mrepeatcount * 8 + mlucknum).setduration(5000); valueanimator.addupdatelistener(new valueanimator.animatorupdatelistener() { @override public void onanimationupdate(valueanimator animation) { int position = (int) animation.getanimatedvalue(); setposition(position%8); } }); valueanimator.addlistener(new animatorlisteneradapter() { @override public void onanimationend(animator animation) { mstartluckposition = mlucknum; //在动画结束的回调函数里加入我们自定义的回调函数 if(onluckpananimendlistener!=null){ onluckpananimendlistener.onanimend(mposition,mluckstr[mposition]); } } }); valueanimator.start(); } public interface onluckpananimendlistener{ void onanimend(int position,string msg); } }
activity代码:
public class mainactivity extends appcompatactivity { private nineluckpan luckpan; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); luckpan = (nineluckpan) findviewbyid(r.id.luckpan); luckpan.setonluckpananimendlistener(new nineluckpan.onluckpananimendlistener() { @override public void onanimend(int position, string msg) { toast.maketext(mainactivity.this, "位置:"+position+"提示信息:"+msg, toast.length_short).show(); } }); } }
效果展示
源码地址:
https://github.com/myml666/nineluckpan
到这里就结束啦!
以上就是android 实现九宫格抽奖功能的详细内容,更多关于android 实现九宫格抽奖的资料请关注其它相关文章!