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

Android 实现九宫格抽奖功能

程序员文章站 2022-03-24 10:28:35
效果展示实现步骤1.生成抽奖矩形:其中每个矩形的宽高相同,长度为整个控件宽度的1/3。代码展示public class nineluckpan extends view { private paint...

效果展示

Android 实现九宫格抽奖功能

实现步骤

1.生成抽奖矩形:

其中每个矩形的宽高相同,长度为整个控件宽度的1/3。

Android 实现九宫格抽奖功能

代码展示

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);
   }
  }
 }
}

效果展示

Android 实现九宫格抽奖功能

2.添加奖品图片:

我们在矩形的中心点画出图片,图片的宽高都为矩形宽高的1/2,其中矩形的中心点通过rectf.centerx()和rectf.centery()获取。

Android 实现九宫格抽奖功能

代码展示(为了方便只展示部分代码)

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);
  }
 }
}

效果展示

Android 实现九宫格抽奖功能

3.实现抽奖动画:

这里我们使用valueanimator使数字从0递增到我们的中奖位置比如3,然后改变递增所在的位置的矩形的背景以实现抽奖的效果,另外为了让用户感到逼真我们需要让抽奖色块多转几圈,同时我们需要将下一次的开始位置设为上一次的结束位置。

Android 实现九宫格抽奖功能

代码展示(为了方便只展示部分代码)

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();
   }
  });
 }
}

效果展示

Android 实现九宫格抽奖功能

虽然效果实现了但是我们发现好像点哪里都能启动动画,因此我们需要调整一下代码使只有点击中心的矩形才开始动画。

//(为了方便只展示部分代码)
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();
   }
  });
 }
}

效果展示

Android 实现九宫格抽奖功能

源码地址:

https://github.com/myml666/nineluckpan

到这里就结束啦!

以上就是android 实现九宫格抽奖功能的详细内容,更多关于android 实现九宫格抽奖的资料请关注其它相关文章!