• 今天分享一个抽奖的类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
  • 相关阅读:
    送给热爱书法的朋友们
    [原创]中秋随笔 祝大家中秋快乐
    Comsenz力邀您的加盟
    夜半冻醒有感
    Comsenz力邀您的加盟
    成熟的谷子先低头
    [转载]10个经典的web2.0配色方案网站
    无法嵌入互操作类型“Microsoft.Office.Interop.Excel.ApplicationClass”
    C#获取真实IP地址及分析
    使用TRY CATCH进行SQL Server异常处理
  • 原文地址:https://www.cnblogs.com/fangyucun/p/4271690.html
Copyright © 2020-2023  润新知