因为company项目中需要做九宫格抽奖活动,以前都没有做过类似的功能,虽然之前在浏览大神们的博客中,无意中也看到了好多关于抽奖的项目,但因为项目中没有需要,一直都没有点击进去看。这次不去看估计不行。直到公司计划要做抽奖功能,才迫不得已上网查找demo


网上找了大半天,好不容易找到了几个demo,下载下来,解压缩包发现竟然里面空空如也,只有几张九宫格的图片,害我白白浪费了几个CSDN积分。后面在eoe网站那发现了一个demo,于是好开心,下载下来后马上导入到工程中,运行看了效果,九宫格是出来了,但效果真不敢恭维,主要是运行不流畅。但我还是进去稍微看了一下demo,基本思路是这样的:定义好九宫格界面,然后开启子线程不断循环修改状态,再通过handler发送消息到主线程中修改界面(子线程不能直接修改界面)。


这个demo虽然功能上实现了,但不是我想要的效果,因为我这一关都不能通过,到了产品那边更加不用说了。那怎么办呢?


于是我想到了一个控件,叫做SurfaceView,做游戏开发的同志们,应该对这个控件不陌生吧?首先介绍一下这个控件:
1.SurfaceView继承于View,多用于游戏开发中
2.可以直接在子线程中运行(其他UI控件都必须在主线程中运行的)。
3.一般的UI控件自定义时都是重写onDraw方法,但在SurfaceView中是通过SurfaceHolder获取Canvas来绘制图形的

这样,下面我开始根据我的想法,把自定义九宫格的步骤说一下。

步骤:

1.计算各位方块的位置
2.绘制每个奖品的方块(主要让界面更加好看)
3.绘制奖品图
4.计算旋转方块的下一步位置
5.绘制旋转方块
6.监听点击开始按钮事件

主要核心技术:
SurfaceView,SurfaceHolder

直接上代码

public class LotteryView extends SurfaceView implements Callback{/*** holder*/private SurfaceHolder mHolder;private List<Prize>prizes;private boolean flags;private int lottery=6;   //设置中奖号码private int current=2;   //抽奖开始的位置private int count=0;   //旋转次数累计private int countDown;    //倒计次数,快速旋转完成后,需要倒计多少次循环才停止private int transfer= 0xffff0000;private int MAX=50;   //最大旋转次数private OnTransferWinningListener listener;public void setOnTransferWinningListener(OnTransferWinningListener listener){this.listener=listener;}public interface OnTransferWinningListener{/*** 中奖回调* @param position*/void onWinning(int position);}/*** 设置中奖号码* @param lottery*/public void setLottery(int lottery) {if(prizes!=null&&Math.round(prizes.size()/2)==0){throw new RuntimeException("开始抽奖按钮不能设置为中奖位置!");}this.lottery = lottery;}/*** 设置转盘颜色* @param transfer*/public void setTransfer(int transfer) {this.transfer = transfer;}/*** 设置奖品集合* @param prizes*/public void setPrizes(List<Prize>prizes){this.prizes=prizes;}@Overridepublic boolean onTouchEvent(MotionEvent event) {handleTouch(event);return super.onTouchEvent(event);}/*** 触摸* @param event*/public void handleTouch(MotionEvent event) {Point touchPoint=new Point((int)event.getX()-getLeft(),(int)event.getY());switch(event.getAction()){case MotionEvent.ACTION_DOWN:Prize prize = prizes.get(Math.round(prizes.size())/2);if(prize.isClick(touchPoint)){if(!flags){setStartFlags(true);prize.click();}}break ;default:break ;}}private class SurfaceRunnable implements Runnable{@Overridepublic void run() {while(flags){Canvas canvas=null;try {canvas = mHolder.lockCanvas();drawBg(canvas);drawTransfer(canvas);drawPrize(canvas);controllerTransfer();} catch (Exception e) {e.printStackTrace();}finally{//涓轰簡璁╂瘡娆$粯鍒跺浘褰㈡椂鑳藉椤哄埄杩涜锛屾渶濂藉皢瑙i攣鏀惧埌寮傚父涓繘琛屽鐞嗭紝涔熷氨鏄锛屽鏋渃anvas涓嶄负绌猴紝閮藉皢鍏跺叧闂紝璁╀笅涓�娆″惊鐜兘澶熼『鍒╄繘琛岀粯鍒�if(canvas!=null)mHolder.unlockCanvasAndPost(canvas);    }}}}//绘制背景private void drawBg(Canvas canvas) {canvas.drawColor(Color.WHITE, Mode.CLEAR);int width = getMeasuredWidth()/3;int x1=0;int y1=0;int x2=0;int y2=0;int len = (int) Math.sqrt(prizes.size());for(int x=0;x<len*len;x++){Prize prize = prizes.get(x);int index=x;x1=getPaddingLeft()+width*(Math.abs(index)%len);y1=getPaddingTop()+width*(index/len);x2=x1+width;y2=y1+width;Rect rect=new Rect(x1,y1,x2,y2);Paint paint=new Paint();paint.setColor(prize.getBgColor());canvas.drawRect(rect, paint);}}//绘制旋转的方块private void drawTransfer(Canvas canvas) {int width = getMeasuredWidth()/3;int x1;int y1;int x2;int y2;int len = (int) Math.sqrt(prizes.size());current=next(current, len);x1=getPaddingLeft()+width*(Math.abs(current)%len);y1=getPaddingTop()+width*((current)/len);x2=x1+width;y2=y1+width;Rect rect=new Rect(x1,y1,x2,y2);Paint paint=new Paint();paint.setColor(transfer);canvas.drawRect(rect, paint);}//控制旋转private void controllerTransfer() {if(count>MAX){countDown++;SystemClock.sleep(count*5);}else{SystemClock.sleep(count*2);}count++;if(countDown>2){if(lottery==current){countDown=0;count=0;setStartFlags(false);if(listener!=null){//切换到主线程中运行post(new Runnable() {@Overridepublic void run() {listener.onWinning(current);}});}}}}public void setStartFlags(boolean flags){this.flags=flags;}//绘制奖品private void drawPrize(Canvas canvas) {int width = getMeasuredWidth()/3;int x1=0;int y1=0;int x2=0;int y2=0;int len = (int) Math.sqrt(prizes.size());for(int x=0;x<len*len;x++){Prize prize = prizes.get(x);int index=x;x1=getPaddingLeft()+width*(Math.abs(index)%len);y1=getPaddingTop()+width*(index/len);x2=x1+width;y2=y1+width;Rect rect=new Rect(x1+width/6,y1+width/6,x2-width/6,y2-width/6);prize.setRect(rect);canvas.drawBitmap(prize.getIcon(), null, rect, null);}}public void start() {setLottery(getRandom());ExecutorService service = Executors.newCachedThreadPool();service.execute(new SurfaceRunnable());}//获取随机中奖数,实际开发中一般中奖号码是服务器告诉我们的private int getRandom(){Random r=new Random();int nextInt =r.nextInt(prizes.size());if(nextInt%(Math.round(prizes.size()/2))==0){//随机号码等于中间开始位置,需要继续摇随机号return getRandom();}return nextInt;}//下一步public int next(int position,int len){int current=position;if(current+1<len){return ++current;}if((current+1)%len==0&&current<len*len-1){return current+=len;}if(current%len==0){return current-=len;}if(current<len*len){return --current;}return current;}public LotteryView(Context context, AttributeSet attrs) {super(context, attrs);mHolder = this.getHolder();mHolder.addCallback(this);}public LotteryView(Context context) {this(context,null);}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}@Overridepublic void surfaceCreated(SurfaceHolder holder) {Canvas canvas=null;try {canvas = mHolder.lockCanvas();drawBg(canvas);drawPrize(canvas);Prize prize = prizes.get(Math.round(prizes.size()/2));prize.setListener(new Prize.OnClickListener() {@Overridepublic void onClick() {start();}});} catch (Exception e) {e.printStackTrace();}finally{if(canvas!=null)mHolder.unlockCanvasAndPost(canvas);    }}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {setStartFlags(false);}/** * 重新测量*/  @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  {  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  int width = Math.min(getMeasuredWidth(), getMeasuredHeight());  setMeasuredDimension(width, width);  }
}

Android打造流畅九宫格抽奖相关推荐

  1. 打造流畅九宫格抽奖活动

    因为company项目中需要做九宫格抽奖活动,以前都没有做过类似的功能,虽然之前在浏览大神们的博客中,无意中也看到了好多关于抽奖的项目,但因为项目中没有需要,一直都没有点击进去看.这次不去看估计不行. ...

  2. Android之九宫格抽奖及大转盘抽奖

    一:先来张效果图 二:实现步骤: -------.九宫格抽奖是从后台服务器获取的数据,图片文字以及抽奖选中位置都是后台控制 一:九宫格抽奖 1九宫格抽奖工具类(里面包含网络请求,不需要的可去掉) pa ...

  3. 九宫格抽奖转盘源码分析

         效果如上图所示,下面对其实现代码进行分析,看能不能破解其抽奖规则.需要引入jquery-1.8.3.min.js和images/9张图片. <!DOCTYPE html PUBLIC ...

  4. Android 打造完美的侧滑菜单/侧滑View控件

    概述 Android 打造完美的侧滑菜单/侧滑View控件,完全自定义实现,支持左右两个方向弹出,代码高度简洁流畅,兼容性高,控件实用方便. 详细 代码下载:http://www.demodashi. ...

  5. 自定义顺序/九宫格抽奖

    效果 唠叨 用一个数组决定外发光边框停留的顺序 取一个随机数,加上之前定好的圈数*盲盒个数,确认最后的奖品是哪个(随机数可后端返回) 根据变换定时的时间,改变每一圈运动的速度 注意:排序的数组和最后奖 ...

  6. android自定义抽奖,Android自定义view制作抽奖转盘

    本文实例为大家分享了Android自定义view制作抽奖转盘的具体代码,供大家参考,具体内容如下 效果图 TurntableActivity package com.bawei.myapplicati ...

  7. python 还原九宫格图片_用Python做一个好玩的朋友圈九宫格抽奖

    最近在朋友圈看到个好玩的抽奖九宫格: 随便点开一个: 设计思路 以朋友圈中看到的1号图做参考,我们需要准备 300*900 的白色底图,搞笑表情图,广告语,中间一个醒目的数字编号,外加下方的嘲讽&qu ...

  8. 九宫格抽奖V1.3.26正版

    简介: 版本号:1.3.26 –九宫格抽奖 1.增加活动内粉丝列表直接修改积分/余额的功能: 2.修复手台手动发送积分/余额时无法到账的问题. 1.支持多活动同时进行,互不影响: 2.可设置每天可抽奖 ...

  9. 基于React跑一个简易版九宫格抽奖

    写在前面,年会将至,需求自然也跟各种抽奖有关啦.最近刚好接了一个紧急的九宫格抽奖需求,顺便也记录一下撸这个简易九宫格的过程吧. 本文可能涉及以下内容: 九宫格布局 九宫格动效 抽奖逻辑处理 前后端联调 ...

最新文章

  1. Socket拉屎模型之二--实践篇
  2. 网站SEO优化如何讨好搜索引擎蜘蛛?
  3. 13.PHP_ThinkPHP
  4. Vue 脚手架生成的项目结构分析||Vue 脚手架的自定义配置
  5. CentOS 6.3安装Nginx开启目录浏览、下载功能
  6. IBATIS中关于iterate$与#的应用
  7. 一次bug调试经验----To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
  8. websocket的用途/场景
  9. DataBinding注意事项Error parsing XML: duplicate attribute以及如何在listview中使用DataBinding...
  10. python四大器_Python编程四大神兽:迭代器、生成器、闭包和装饰器
  11. 程序员都必须了解的18个Python模式程序片段
  12. Linux chapter 4
  13. NAT with same subnetwork
  14. visio2003 FK
  15. 树的叶子结点与完全二叉树结点计算方法
  16. Google Dapper,大规模分布式系统的跟踪系统
  17. 高性能JSON框架之FastJson的简单使用
  18. VS2019下编译与配置GSL2.7【Release x64版】
  19. Linux运维常用知识(1)
  20. 不要瞎折腾,几张思维导图就讲清搜索引擎优化(SEO)核心点

热门文章

  1. Nginx_01_Nginx三大基础功能(静态服务器、虚拟主机、负载均衡/服务端代理)
  2. 电脑投屏到电视怎么操作_无线投屏器应用
  3. java命令行打包war_命令行打包 war文件
  4. 史上最简单的Spring Security教程(二十八):CA登录与默认用户名密码登录共存详细实现及配置
  5. nuxt.js实战asyncdata服务端渲染
  6. 【转载】入坑KeePass(七)Keepass 2.x 之 同步与触发器
  7. 《数字图像处理》笔记—空间滤波
  8. 访问网址 token的格式_一文彻底搞懂Cookie、Session、Token到底是什么
  9. Mac安装与配置jmeterjmeter的使用jmeter生成性能测试报告
  10. 耀华仪表A9数据解析(C#)