Android实现幸运大转盘功能

image.png

参考:https://blog.csdn.net/lwang057/article/details/78829137

功能概述:

旋转之后根据随机数来影响最后指针停留的位置,也就是旋转的角度。有两种转法,指针转和转盘转,这里是转盘转,转起来后有一个跑马灯的效果。

布局:




    

        

            

                

                
            

            

            
                
                
            
        

        

            

            
            
        

    

动画文件:


image.png


    
    


Activity文件(kotlin):

@Layout(R.layout.activity_rotary)
class MyRotaryActivity : BaseActivity(),View.OnClickListener {
   //找到需要旋转的组件
    @BindView(R.id.cl_circle)
    lateinit var clCircle : ConstraintLayout
  //抽奖按钮
    @BindView(R.id.ll_start_rotate)
    lateinit var startRotate : LinearLayout

    //初始化一些必要的属性
    lateinit var mStartAnimation : Animation
    private lateinit var mEndAnimation : Animation
        fun isEndAnimation()=::mEndAnimation.isInitialized
    private var isRunning = false
    private var mPrizeGrade = 8 //奖品级别,0代表没有
    private var mItemCount = 8
    //4,7->金币1个 88%   //2->金币50 10%  //3->爱奇艺  0.5%  //5->绿萝  0.5% //6->口罩  1%  //0->苹果 0%  //->京东 0%
    private var mPrizePosition = arrayListOf(4, 7, 2, 3, 5, 6, 0, 1)  //奖品在转盘中的位置(到达一等奖的距离)

    //抽奖数据(一般情况下抽奖数据需要请求服务器获取,随机概率也可以由服务端做)
    private var data = LuckyWheelData.Data()

 override fun initViews() {
    //初始化动画
        mStartAnimation = AnimationUtils.loadAnimation(this, R.anim.rotary_anim)
        val acc = AccelerateInterpolator()
        mStartAnimation.interpolator = acc
}

    override fun initDatas(parameter: JumpParameter?) {
    }

    @RequiresApi(Build.VERSION_CODES.M)
    override fun setEvents() {
        //抽奖监听
        startRotate.setOnClickListener(this)
    }

    //设置的点击事件,点击中间抽奖启动旋转动画
    override fun onClick(v: View?) {
        //如果抽奖次数大于0那么可以抽奖
        if(data.surplusLuckDrawCount > 0){
            isRunning = true
            //禁止点击抽奖,抽奖完成后可以点击
            startRotate.isClickable = false
        }else{
            isRunning = false
            ToastUtils.showShort("没有抽奖次数了")
        }
        // 未抽过奖并有抽奖的机会
        if (isRunning) {
            //请求后台传递的抽取物品,根据抽取物品来选择realPositin就行了
//            requestStart()
            //直接开转
            //重置转盘开始旋转
            isRunning = false;
            mStartAnimation.reset();
            clCircle.startAnimation(mStartAnimation)

            if(isEndAnimation()){
                mEndAnimation.cancel()
            }

            Handler().postDelayed(Runnable {
                endAnimation()
            },1000)
        }
    }
}

    // 结束动画,慢慢停止转动,抽中的奖品定格在指针指向的位置
    private fun endAnimation() {
        var position = mPrizePosition[0]  //mPrizeGrade - 1
        //最垃圾奖品位置计算
        var toDegreeMin = 360 / mItemCount * (position - 0.5f + 1 )
        var random = Random()
//        //举例,随机从100里面取一个整数,小于88就1金币
        var realPosition = 0
        var randomInt = random.nextInt(200)
        var endString = ""
        if(randomInt < 88){
            //转到1金币
            realPosition = 45 * 5
            endString = "转到1金币 - 黄色"
        }else if(randomInt in 88..176){
            //转到1金币
            realPosition = 0
            endString = "转到1金币 - 白色"
        }else if(randomInt in 176..196){
            //转到金币50
            realPosition =  45 * 2
            endString = "转到金币50"
        }else if(randomInt in 196..197){
            //爱奇艺
//            realPosition =  45
            //转到金币50
            realPosition =  45 * 2
            endString = "爱奇艺"
        }else if(randomInt in 197..198){
            //绿萝
//            realPosition = 45 * 7
            //转到金币50
            realPosition =  45 * 2
            endString = "绿萝"
        }else if(randomInt in 198..200){
            //口罩
//            realPosition = 45 * 6
            //转到金币50
            realPosition =  45 * 2
            endString = "口罩"
        }
        var toDegree = toDegreeMin + realPosition + 360 * 3; //5周 + 偏移量

        // 按中心点旋转 toDegree 度
        // 参数:旋转的开始角度、旋转的结束角度、X轴的伸缩模式、X坐标的伸缩值、Y轴的伸缩模式、Y坐标的伸缩值
        mEndAnimation = RotateAnimation(0F, toDegree, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        mEndAnimation.setDuration(3000) // 设置旋转时间
        mEndAnimation.setRepeatCount(0) // 设置重复次数
        mEndAnimation.setFillAfter(true)// 动画执行完后是否停留在执行完的状态
        mEndAnimation.setInterpolator(DecelerateInterpolator()) // 动画播放的速度
        mEndAnimation.setAnimationListener(object : Animation.AnimationListener{
            override fun onAnimationStart(animation: Animation?) {
            }

            override fun onAnimationEnd(animation: Animation?) {
                isRunning = false
                startRotate.isClickable = true
//                ToastUtils.showShort(endString)
                showPopup(endString)
            }

            override fun onAnimationRepeat(animation: Animation?) {
            }
        })
        clCircle.startAnimation(mEndAnimation)
        mStartAnimation.cancel()
    }

    //停止动画(异常情况,没有奖品)
    fun stopAnimation() {
        //转盘停止回到初始状态
        if (isRunning) {
            mStartAnimation.cancel()
//            mLuckyTurntable.clearAnimation();
            clCircle.clearAnimation()
            isRunning = false
        }
    }

你可能感兴趣的:(Android实现幸运大转盘功能)