今天分享一个抽奖的类Lottery

/*

 * Copyright (C) 2014 Jason Fang ( [email protected] )

 *

 * 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

你可能感兴趣的:(分享)