Android 九宫格抽奖
来源:互联网 发布:threadfactory vb 编辑:程序博客网 时间:2024/05/21 09:10
思路: 在开始绘制九宫格之前,我们先重写onMeasure方法,主要是为了让九宫格成为一个正方形,
SurfaceView一般不是通过重写onDraw方法来绘制控件的,那么怎么获取到Canvas呢?主要是通过SurfaceHolder监听Callback事件来获取的 ,有了对象SurfaceHolder对象,我们就可以获取到Canvas对象了,下面开始真正的绘制工作。
步骤:
1.计算各位方块的位置
2.绘制每个奖品的方块(主要让界面更加好看)
3.绘制奖品图
4.计算旋转方块的下一步位置
5.绘制旋转方块
6.监听点击开始按钮事件
主要核心技术:
SurfaceView,SurfaceHolder
OK,有了基本步骤,接下来就是根据步骤一步一步来进行了。 代码如下
<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.myapplication.MainActivity"> <com.example.myapplication.LotteryView android:id="@+id/nl" android:layout_width="368dp" android:layout_height="495dp" tools:layout_editor_absoluteY="8dp" tools:layout_editor_absoluteX="8dp" /></android.support.constraint.ConstraintLayout>
package com.example.myapplication;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.widget.Toast;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LotteryView nl; setContentView(R.layout.activity_main); nl = (LotteryView) findViewById(R.id.nl); int[] prizesIcon = {R.drawable.navicon_a, R.drawable.navicon_b, R.drawable.navicon_c, R.drawable.navicon_d, R.drawable.navicon_e, R.drawable.navicon_a, R.drawable.navicon_d, R.drawable.navicon_b, R.drawable.navicon_e}; final List<Prize> prizes = new ArrayList<Prize>(); for (int x = 0; x < 9; x++) { Prize lottery = new Prize(); lottery.setId(x + 1); lottery.setName("Lottery" + (x + 1)); Bitmap bitmap = BitmapFactory.decodeResource(getResources(), prizesIcon[x]); lottery.setIcon(bitmap); if ((x + 1) % 2 == 0) { lottery.setBgColor(0xff4fccee); } else if (x == 4) { lottery.setBgColor(0xffffffff); } else { lottery.setBgColor(0xff00ff34); } prizes.add(lottery); } nl.setPrizes(prizes); nl.setOnTransferWinningListener(new LotteryView.OnTransferWinningListener() { @Override public void onWinning(int position) { Toast.makeText(getApplicationContext(), prizes.get(position).getName(), Toast.LENGTH_SHORT).show(); } }); }}
package com.example.myapplication;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Point;import android.graphics.PorterDuff.Mode;import android.graphics.Rect;import android.os.SystemClock;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android.view.SurfaceView;import java.util.List;import java.util.Random;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;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; } @Override public 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,getMeasuredWidth())){ if(!flags){ setStartFlags(true); prize.click(); } } break ; default: break ; } } private class SurfaceRunnable implements Runnable{ @Override public 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() { @Override public 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 current,int len){ if(current+1<len){ return ++current; } if((current+1)%len==0¤t<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); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public 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() { @Override public void click() { start(); } }); } catch (Exception e) { e.printStackTrace(); }finally{ if(canvas!=null) mHolder.unlockCanvasAndPost(canvas); } } @Override public 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); }}
package com.example.myapplication;import android.graphics.Bitmap;import android.graphics.Point;import android.graphics.Rect;/** * Created by Cr on 2017/9/18. * 奖品的属性 */ class Prize { int Id; String Name; Bitmap Icon; int BgColor; Rect rect; public OnClickListener getListener() { return listener; } public void setListener(OnClickListener listener) { this.listener = listener; } OnClickListener listener; public Rect getRect() { return rect; } public void setRect(Rect rect) { this.rect = rect; } public int getId() { return Id; } public void setId(int id) { Id = id; } public String getName() { return Name; } public void setName(String name) { Name = name; } public Bitmap getIcon() { return Icon; } public void setIcon(Bitmap icon) { Icon = icon; } public int getBgColor() { return BgColor; } public void setBgColor(int bgColor) { BgColor = bgColor; } public interface OnClickListener{ void click(); } public void click(){ listener.click(); } public boolean isClick (Point touchPoint,int width){ if (touchPoint.x < width/3*2&touchPoint.x > width/3&touchPoint.y < width/3*2&touchPoint.y > width/3){ return true; }else{ return false; } }}
阅读全文
0 0
- Android九宫格抽奖
- Android 九宫格抽奖
- Android打造流畅九宫格抽奖
- 九宫格抽奖使用
- 九宫格抽奖
- js:九宫格抽奖
- js九宫格抽奖功能
- JavaScript实现基本九宫格抽奖
- jquery九宫格抽奖转盘插件
- 【lufylegend】年会九宫格抽奖程序
- 模拟抽奖的九宫格动画效果
- 九宫格抽奖停止位置的设置
- 打造流畅九宫格抽奖活动
- 用jquery实现九宫格抽奖
- jQuery九宫格抽奖功能的实现
- 九宫格抽奖- 前后端代码
- 应用二维数组实现抽奖功能(九宫格)
- jQuery微信手机端九宫格抽奖代码特效
- 分库分表的工具
- 虚拟机 安装VMware Tools
- JS中new操作符与函数返回值return
- Redis乐观锁控制事务
- JavaWeb 通过ios上传图片旋转问题
- Android 九宫格抽奖
- js实现食堂里的长桌问题
- 卷积和池化层笔记
- vue-cli 父子组件插头传递 标签slot 应用
- 解决Android Stdio打开项目maven库被墙(Failed to resolve: com.android.support)
- 基数排序(LSD+MSD)详解
- js总结
- OpenFlow好文集锦-OpenFlow1.0协议解析
- Android实战——GreenDao3.2的使用,爱不释手