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
  • 相关阅读:
    无法跨越程序集边界使用程序集,因为该成员包含的某个类型具有一个为嵌入互操作类型的泛型类型参数。
    arcengine右键实现new group layer的功能
    winform进度条
    arcgisengine实现矩形转面
    win10 SVN不能显示图标
    关于VS打包程序无法弹出主界面的问题
    ArcGIS Javascript 异常之No 'Access-Control-Allow-Origin' header
    ArcGIS JavaScript API异常之onExtentChange事件覆盖onClick事件
    ArcGIS AddIN 之 DockPanel 界面空白
    关于JQuery设置checkbox checked 的问题
  • 原文地址:https://www.cnblogs.com/fangyucun/p/4271690.html
Copyright © 2011-2022 走看看