/*
* Copyright (C) 2014 Jason Fang ( ijasonfang@gmail.com )
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package fyc.framework.anim; import java.util.concurrent.TimeUnit; import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.os.Build;
import android.os.CountDownTimer;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import fyc.framework.util.Flog;
import fyc.framework.util.RandomUtils; /**
* @author Jason Fang
* @datetime 2015年1月29日 下午7:19:36
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class Lottery {
static final boolean DEBUG = true; private static final int LOADING_UNIT_DEGREE = 360 * 5;
private static final int LOADING_DURATION = 720 * 5;
private static final long LOTTERY_TIME_OUT = TimeUnit.SECONDS.toMillis(5); private ImageView mImageView;
private ObjectAnimator mLoadingAnim;
private float mInitDegree = 0;
private int mMaxLevel = 10;
private int mUnitDegree;
private int[] mLevelMap;
private long mTimeout = LOTTERY_TIME_OUT; private boolean mIsLottering = false;
private boolean mIsInStop = false; private OnLotteryListener mListener;
private LotteryTimeOut mLotteryTimeOut; private Lottery(ImageView imageView, OnLotteryListener listener) {
mImageView = imageView;
mListener = listener;
} public static Lottery newInstance(ImageView imageView, OnLotteryListener listener) {
return new Lottery(imageView, listener);
} public Lottery setLevel(int level) {
mMaxLevel = level;
mUnitDegree = 360 / mMaxLevel;
return this;
} public Lottery setLevelMap(int[] levelMap) {
if (levelMap.length != mMaxLevel) {
throw new IllegalArgumentException("levelMap length must equal MaxLevel!");
}
mLevelMap = levelMap;
return this;
} public Lottery setTimeOut(int timeout) {
if (timeout <= 0) return this; mTimeout = TimeUnit.SECONDS.toMillis(timeout);
return this;
} public Lottery start() {
if (mIsLottering) return this;
mIsLottering = true; if (DEBUG) Flog.i("start"); loadingAnimStart(); if (mListener != null) {
mListener.onLotteryStart();
} mLotteryTimeOut = new LotteryTimeOut();
mLotteryTimeOut.start(); return this;
} public void stop(int level) {
if (mIsInStop) return;
mIsInStop = true; if (mLotteryTimeOut != null) {
mLotteryTimeOut.cancel();
} int levelAward = getLevelAward(level); if (mLoadingAnim != null && mLoadingAnim.isRunning()) {
mLoadingAnim.cancel();
} if (levelAward < 0 || levelAward > mMaxLevel) {
throw new IllegalArgumentException("level cannot below 0 or than MaxLevel!");
} float stopDegree = 0;
if (levelAward == 0) {
stopDegree = LOADING_UNIT_DEGREE - mUnitDegree / 2;
} else {
stopDegree = (LOADING_UNIT_DEGREE - mUnitDegree / 2) + RandomUtils.getRandom(mUnitDegree * levelAward + 5, mUnitDegree * (levelAward + 1) - 5);
} float startDegree = 0f;
if (mLoadingAnim != null) {
startDegree = (Float)mLoadingAnim.getAnimatedValue() % 360;
} else {
throw new RuntimeException("Must invoke start first!");
} long duration = (long)((stopDegree - startDegree) / ((LOADING_UNIT_DEGREE / (float)LOADING_DURATION))); stopAnimStart(startDegree, stopDegree, duration, levelAward); mInitDegree = stopDegree;
} int getLevelAward(int level) {
if (mLevelMap == null || mLevelMap.length == 0 || level == 0) return level;
return mLevelMap[level - 1];
} void loadingAnimStart() {
mLoadingAnim = ObjectAnimator.ofFloat(mImageView, "rotation", mInitDegree % 360, LOADING_UNIT_DEGREE);
mLoadingAnim.setInterpolator(new LinearInterpolator());
mLoadingAnim.setRepeatCount(ValueAnimator.INFINITE);
mLoadingAnim.setDuration(LOADING_DURATION);
mLoadingAnim.start();
} void stopAnimStart(float startDegree, float stopDegree, long duration, int levelAward) {
ObjectAnimator anim = ObjectAnimator.ofFloat(mImageView, "rotation", startDegree, stopDegree);
anim.setInterpolator(new DecelerateInterpolator());
anim.setDuration(duration * 2);
anim.addListener(new LotteryAnimatorListener(levelAward));
anim.start();
} class LotteryTimeOut extends CountDownTimer { public LotteryTimeOut() {
super(mTimeout, mTimeout);
} @Override
public void onTick(long millisUntilFinished) {
} @Override
public void onFinish() {
stop(0);
} } class LotteryAnimatorListener implements AnimatorListener { private int mLevel; public LotteryAnimatorListener() {
} public LotteryAnimatorListener(int level) {
mLevel = level;
} @Override
public void onAnimationStart(Animator animation) {
} @Override
public void onAnimationEnd(Animator animation) {
if (mListener != null) {
mListener.onLotteryStop(mLevel);
mIsLottering = false;
mIsInStop = false;
}
} @Override
public void onAnimationCancel(Animator animation) {
} @Override
public void onAnimationRepeat(Animator animation) {
} } public interface OnLotteryListener {
public void onLotteryStart();
public void onLotteryStop(int level);
}
}

如果要指针初始化指向圆盘的缝隙. 需要做简要的修改!

DEMO

mLottery = Lottery.newInstance(mWheel, new OnLotteryListener() {

            @Override
public void onLotteryStop(int level) {
Flog.i("onLotteryStop:" + level);
} @Override
public void onLotteryStart() {
Flog.i("onLotteryStart");
}
})
.setLevel(10)  //总共几个奖
.setLevelMap(new int[]{5, 1, 1, 1, 1, 1, 1, 1, 1, 1}) //映射奖项
.setTimeOut(4);

获取到服务器端值之后调用

mLottery.stop(5);  //参数为几等奖

今天分享一个抽奖的类Lottery的更多相关文章

  1. 分享一个Snackbar工具类 SnackbarUtils;

    分享一个Snackbar工具类,源代码也是在Github上面找的,自己做了一下修改: 功能如下: 1:设置Snackbar显示时间长短                 1.1:Snackbar.LEN ...

  2. [分享]一个String工具类,也许你的项目中会用得到

    每次做项目都会遇到字符串的处理,每次都会去写一个StringUtil,完成一些功能. 但其实每次要的功能都差不多: 1.判断类(包括NULL和空串.是否是空白字符串等) 2.默认值 3.去空白(tri ...

  3. 分享一个Redis帮助类

    最近在项目中使用了redis来存储已经下载过的URL,项目中用的是ServiceStack来操作Redis,一开始ServiceStack的版本用的是最新的,后来发现ServiceStack已经商业化 ...

  4. 分享一个FileUtil工具类,基本满足web开发中的文件上传,单个文件下载,多个文件下载的需求

    获取该FileUtil工具类具体演示,公众号内回复fileutil20200501即可. package com.example.demo.util; import javax.servlet.htt ...

  5. 分享一个手机端好用的jquery ajax分页类

    分享一个手机端好用的jquery ajax分页类 jquery-ias.min.js 1,引入jquery-ias.min.js 2,调用ajax分页 <script type="te ...

  6. .Net Excel 导出图表Demo(柱状图,多标签页) .net工具类 分享一个简单的随机分红包的实现方式

    .Net Excel 导出图表Demo(柱状图,多标签页) 1 使用插件名称Epplus,多个Sheet页数据应用,Demo为柱状图(Epplus支持多种图表) 2 Epplus 的安装和引用 新建一 ...

  7. 分享一个SqliteHelper类

    分享一个SqliteHelper类 SQLite作为一个本地文件数据库相当好用,小巧.快速.支持事务.关系型,甚至可以运行在Android上.在很久以前的一个项目中,我们用过它来将接收到的数据做本地统 ...

  8. 分享一个简单的C#的通用DbHelper类(支持数据连接池)

    每次新项目的时候,都要从头去找一遍数据库工具类.这里分享一个简单实用的C#的通用DbHelper工具类,支持数据连接池. 连接池配置 <connectionStrings> <add ...

  9. 分享一个自己用的Objective-C的Http接连类

    很久没有更新博客了,所以分享一个. @protocol HttpListenerDelegate; @interface BaseHttp : NSObject { } @property (nona ...

随机推荐

  1. C++设计模式——建造者模式

    建造者模式 在GOF的<设计模式 可复用面向对象软件的基础>中是这样说的:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 这句话,似懂非懂的.一个复杂对象的创建 ...

  2. C++ 我想这样用(二)

    话接上篇,从纯C环境转C++环境需要注意些什么呢? 没错,虽然C++曾号称兼容C,而且很多人甚至觉得C就是C++子集,但是c脑残粉一定知道,两者有很大的不同! 下面这些要点是比较突出的,后期我再补充其 ...

  3. fork之后发生了什么(基于3.16-rc4)

    在linux c编程中,我们可以使用fork,vfork,clone三个系统调用来创建子进程.下面我们先分析下fork系统调用的实现原理.代码如下(kernel/fork.c): #ifdef __A ...

  4. ubuntu使用问题与解决记录[持续更新]

    1. 添加到计划任务 为脚本增加可执行权限 sudo chmod +x yeelink.sh 将脚本加入cronjob(计划任务) sudo crontab -e 在cornjob文件中添加下面一行, ...

  5. Hadoop Hive概念学习系列之为什么Hive里,要用mysql?(四)

    想说的是,hive只是个工具,包括它的数据分析,依赖于mapreduce,它的数据管理,依赖于外部系统. metastore_db,是在哪目录下运行,在哪里产生数据. 由此可见,你在哪路径下,执行hi ...

  6. java的math常用方法

    鉴于java求整时欲生欲死,整理常用math如下: 1: java取整 a:floor向下取整 用法:Math.floor(num) Math.floor(1.9)//1               ...

  7. JSF 2 multiple select dropdown box example

    In JSF, <h:selectManyMenu /> tag is used to render a multiple select dropdown box – HTML selec ...

  8. ASP.NET网站中设置404自定义错误页面

    在用ASP.NET WebForm开发一个网站时,需要自定义404错误页面. 做法是这样的 在网站根目录下建立了一个404.html的错误页面,然后在Global.asax文件中,加入如下代码: &l ...

  9. 在Android4.0中Contacts拨号盘界面剖析(源码)

      通过在 ViewPager 的适配器对象中,发现过一下三行代码 private DialpadFragment mDialpadFragment; private CallLogFragment ...

  10. HDU 5773 The All-purpose Zero (变形LIS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5773 0可以改变成任何数,问你严格递增的子序列最长是多少. 猜测0一定在最长上升子序列中用到,比如2 ...