zoukankan      html  css  js  c++  java
  • 今天分享一个抽奖的类Lottery

    /*
     * 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);  //参数为几等奖

     

    欢迎分享转载,转载请注明出处 http://www.cnblogs.com/fangyucun
  • 相关阅读:
    C语言 realloc为什么要有返回值,realloc返回值具体解释/(解决随意长度字符串输入问题)。
    opencv中的vs框架中的Blob Tracking Tests的中文注释。
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 棋盘多项式
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
    Java实现 蓝桥杯VIP 算法提高 分苹果
  • 原文地址:https://www.cnblogs.com/fangyucun/p/4271690.html
Copyright © 2011-2022 走看看