在慕课上看了鸿洋大神的课程,在此记录下来,小伙伴们可以直接去网站下载素材,传送门

幸运转盘类

package com.example.surfaceviewdemo;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.SurfaceHolder;
import android.view.SurfaceView;/*** Created by FangJu on 2019/12/3.*/
public class LuckyPan extends SurfaceView implements SurfaceHolder.Callback, Runnable {private SurfaceHolder mHolder;private Canvas mCanvas;//用于绘制的线程private Thread t;//控制线程的开关private boolean isRunning;//盘块的奖项private String[] mStrs = new String[]{"单反相机", "IPAD", "恭喜发财", "IPHONE", "服装一套", "恭喜发财"};//盘块的图片private int[] mImgs = new int[]{R.drawable.danfan, R.drawable.ipad, R.drawable.f040, R.drawable.iphone, R.drawable.meizi, R.drawable.f015};//盘块的颜色private int[] mColors = new int[]{0xFFFFC300, 0XFFF17E10, 0xFFFFC300, 0XFFF17E10, 0xFFFFC300, 0XFFF17E10};//与图片对应的Bitmapprivate Bitmap[] mImgsBitmap;//背景private Bitmap mBgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg2);//盘块的数量private int mItemCount = 6;//盘块的范围private RectF mRange = new RectF();//盘块的直径private int mRadius;//盘块的画笔private Paint mArcPaint;//盘块字体的画笔private Paint mTextPaint;//文字的大小private float mTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics());//滚动的速度private double mSpeed = 0;//开始的角度private volatile float mStartAngle = 0;//转盘的中心位置private int mCenter;//转盘的外边距,以paddLeft为准private int mPadding;//判断是否点击了停止按钮private boolean isShouldEnd;public LuckyPan(Context context) {this(context, null);}public LuckyPan(Context context, AttributeSet attrs) {super(context, attrs);mHolder = getHolder();mHolder.addCallback(this);//可获得焦点setFocusable(true);setFocusableInTouchMode(true);//设置常量setKeepScreenOn(true);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width = Math.min(getMeasuredWidth(), getMeasuredHeight());mPadding = getPaddingLeft();//半径mRadius = width - mPadding * 2;//中心点mCenter = width / 2;setMeasuredDimension(width, width);}@Overridepublic void surfaceCreated(SurfaceHolder holder) {//初始化盘块的画笔mArcPaint = new Paint();mArcPaint.setAntiAlias(true);mArcPaint.setDither(true);//初始化字体的画笔mTextPaint = new Paint();mTextPaint.setColor(Color.WHITE);mTextPaint.setTextSize(mTextSize);//初始化盘块的范围mRange = new RectF(mPadding, mPadding, mPadding + mRadius, mPadding + mRadius);//初始化图片mImgsBitmap = new Bitmap[mItemCount];for (int i = 0; i < mItemCount; i++) {mImgsBitmap[i] = BitmapFactory.decodeResource(getResources(), mImgs[i]);}isRunning = true;t = new Thread(this);t.start();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {isRunning = false;}@Overridepublic void run() {while (isRunning) {long start = System.currentTimeMillis();draw();long end = System.currentTimeMillis();if (end - start < 50) {try {Thread.sleep(50 - (end - start));} catch (InterruptedException e) {e.printStackTrace();}}}}private void draw() {try {mCanvas = mHolder.lockCanvas();if (mCanvas != null) {//绘制背景drawBg();//绘制盘块float tempAngle = mStartAngle;float sweepAngle = 360 / mItemCount;for (int i = 0; i < mItemCount; i++) {//绘制盘块mArcPaint.setColor(mColors[i]);mCanvas.drawArc(mRange, tempAngle, sweepAngle, true, mArcPaint);//绘制文本drawText(tempAngle, sweepAngle, mStrs[i]);//绘制IcondrawIcon(tempAngle, mImgsBitmap[i]);tempAngle += sweepAngle;}mStartAngle += mSpeed;//如果点击了停止按钮if (isShouldEnd) {mSpeed -= 1;}if (mSpeed <= 0) {mSpeed = 0;}}} catch (Exception e) {} finally {if (mCanvas != null)mHolder.unlockCanvasAndPost(mCanvas);}}/*** 点击启动旋转* @param index 奖项的位置*/public void luckyStart(int index) {//计算每一项的角度float angle = 360 / mItemCount;//计算每一项中奖范围(当前index)//1-> 150~210//0-> 210~270float from = 270 - (index + 1) * angle;float end = from + angle;//设置停下来需要旋转的距离float targetFrom = 4 * 360 + from;float targetEnd = 4 * 360 + end;float v1 = (float) ((-1 + Math.sqrt(1 + 8 * targetFrom)) / 2);float v2 = (float) ((-1 + Math.sqrt(1 + 8 * targetEnd)) / 2);mSpeed = v1 + Math.random() * (v2 - v1);isShouldEnd = false;}public void luckyEnd() {mStartAngle = 0;isShouldEnd = true;}public boolean isStart() {return mSpeed != 0;}public boolean isShouldEnd() {return isShouldEnd;}/*** 绘制Icon** @param tempAngle* @param mImg*/private void drawIcon(float tempAngle, Bitmap mImg) {//设置图片的宽度为直径的1/8int imgWidth = mRadius / 8;//角度=(起始角度+每个盘块一半的角度)* 1度的大小float angle = (float) ((tempAngle + 360 / mItemCount / 2) * Math.PI / 180);//图片中心点的坐标int x = (int) (mCenter + mRadius / 2 / 2 * Math.cos(angle));int y = (int) (mCenter + mRadius / 2 / 2 * Math.sin(angle));//确定图片的位置Rect rect = new Rect(x - imgWidth / 2, y - imgWidth / 2, x + imgWidth / 2, y + imgWidth / 2);mCanvas.drawBitmap(mImg, null, rect, null);}/*** 绘制文本** @param tempAngle* @param sweepAngle* @param mStr*/private void drawText(float tempAngle, float sweepAngle, String mStr) {Path path = new Path();path.addArc(mRange, tempAngle, sweepAngle);//利用水平偏移量让文字居中float mTextWidth = mTextPaint.measureText(mStr);int hOffset = (int) ((mRadius * Math.PI / mItemCount) / 2 - mTextWidth / 2);//垂直偏移量int vOffset = mRadius / 2 / 6;mCanvas.drawTextOnPath(mStr, path, hOffset, vOffset, mTextPaint);}/*** 绘制背景*/private void drawBg() {Log.d("TAG", "drawBg: ");mCanvas.drawColor(Color.WHITE);mCanvas.drawBitmap(mBgBitmap, null, new Rect(mPadding / 2, mPadding / 2, getMeasuredWidth() - mPadding / 2, getMeasuredHeight() - mPadding / 2), null);}
}

测试类

package com.example.surfaceviewdemo;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;public class MainActivity extends AppCompatActivity {private LuckyPan mLuckyPan;private ImageView mStartBtn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mLuckyPan = findViewById(R.id.luckyPan);mStartBtn = findViewById(R.id.start_btn);mStartBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (!mLuckyPan.isStart()) {mLuckyPan.luckyStart(2);mStartBtn.setImageResource(R.drawable.stop);} else {if (!mLuckyPan.isShouldEnd()) {mLuckyPan.luckyEnd();mStartBtn.setImageResource(R.drawable.start);}}}});}
}

测试布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"android:background="@android:color/white"tools:context=".MainActivity"><com.example.surfaceviewdemo.LuckyPanandroid:id="@+id/luckyPan"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_centerInParent="true"android:padding="30dp"></com.example.surfaceviewdemo.LuckyPan><ImageViewandroid:id="@+id/start_btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:src="@drawable/start" /></RelativeLayout>

SurfaceView实现抽奖转盘相关推荐

  1. 详解与重构hyman《Android SurfaceView实战 打造抽奖转盘》

    详解与重构hyman<Android SurfaceView实战 打造抽奖转盘> 作者:邵励治 一.概述--关于SurfaceView您不得不知道的二三事 1.SurfaceView是干什 ...

  2. Android实现抽奖转盘

    慕客网视频传送门:http://www.imooc.com/learn/444 好久都没去慕客网了,虽然这次学习的是一个比较老的视频了,但是总比不学的好.(末尾附源码) 在学习之前,先来了解一波Sur ...

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

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

  4. python转盘抽奖_react 抽奖转盘 ----小计

    前言 很久没有写过小组件了,突然想做一个抽奖转盘,就花半天时间做一个,很简单 1.支持把一个圆盘分成n瓣. 2.实现转动动画. 3.弄个指针样式意思意思. 4.遇到抽奖的需求改吧改吧就能用了. 图是这 ...

  5. 抽奖 开源 html5,抽奖转盘.html · smilestone/awardRotate - Gitee.com

    jQuery 抽奖转盘 #box{width: 340px;height: 340px; position: absolute; left:50%;top:50%;margin-left:-170px ...

  6. html旋转代码_用CSS实现一个抽奖转盘(附详细代码+思路)

    原文:https://www.cnblogs.com/wenruo/p/9732704.html 先上效果 基本是用CSS实现的,没有用图片,加一丢丢JS.不过没有考虑太多兼容性. 首先画一个转盘 & ...

  7. Html5-Canvas实现简易的抽奖转盘

    ###Html5实现抽奖转盘效果 1.实现的基本效果 2.主要的内容 html5中canvas标签的使用 jQueryRotate.js旋转插件 3.主要html代码 <body>< ...

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

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

  9. 利用jqueryRotare实现抽奖转盘

    很多公司到了年底都会做一些抽奖活动来刺激.吸引.粘住客户,比如抽奖转盘活动. 前几天用一个jqueryRotate插件实现了转盘的效果.比起那些很炫丽的flash是稍逊点,但也基本实现了需求 效果图: ...

最新文章

  1. automybatis mysql_mybatis-plus:使用Mybatis-AutoGenerator代码生成器(1)
  2. 北航计算机应用基础 统考,北航10秋学期《计算机应用基础》模拟题.doc
  3. 机械臂中的四元素转为旋转矩阵_雅克比矩阵(上)雅克比推导
  4. 使用pycharm创建一个项目 利用自己建好的虚拟环境
  5. 关于指针int *p=a和*p=a的纠正
  6. 使用base64 对Json 的返回数据进行优化
  7. ios 根据文字数量计算UILabel高度(已修改)
  8. 区块链技术将有可能彻底颠覆音乐行业,思想启迪+P2Ptech,end
  9. Snowflake id生成器
  10. 【设计鉴赏】超美的墨汁喷溅字体
  11. H266VVC电子书开放下载啦
  12. 3DGIS地理信息系统设计方案
  13. CNN实现简单语音识别(单词识别)
  14. RabbitMQ登录时guest用户提示User can only log in via localhost
  15. ADDA数模转换(PCF8591)
  16. 电影《龙卷风》主题旋律你一定听过
  17. 业务流程管理(BPM)系统的九大必备特点
  18. 智能宠物饲养系统设计
  19. iPad协议接口-稳定版
  20. SolidWorks 如何制作装配体

热门文章

  1. 战场模拟器过检测集体凉凉?没关系,你还可以这样电脑玩吃鸡匹配手机
  2. 贝乐机器人俱乐部_贝乐机器人编程俱乐部机器人课程介绍
  3. 1份投入10倍收益,后疫情时代线上营销如何实现“小投入大回报“?
  4. sql 库存先进先出原则,统计库存
  5. HTML标记【表格的建立】!
  6. 多线程的四种实现方式
  7. 新手用降低转速来解决显卡风扇噪音大的问题(有图有真相)
  8. linux fopen 段错误,fopen出现段错误,不解[已解决]
  9. 编译原理 —— 语言的定义
  10. 基线_定位技术超短基线水声的系统校准