当前位置: 萬仟网 > 移动技术>移动开发>Android > Android 实现九宫格抽奖功能

Android 实现九宫格抽奖功能

2021年03月25日  | 萬仟网移动技术  | 我要评论
效果展示实现步骤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 实现九宫格抽奖的资料请关注萬仟网其它相关文章!

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
Copyright © 2017-2021  萬仟网 保留所有权利. 粤ICP备17035492号-1
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com