美文网首页
Android实现幸运大转盘功能

Android实现幸运大转盘功能

作者: SeekLife0 | 来源:发表于2022-02-25 21:12 被阅读0次
    image.png
    参考:https://blog.csdn.net/lwang057/article/details/78829137

    功能概述:

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

    布局:

    <?xml version="1.0" encoding="utf-8"?>
    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/scroll_view_wheel"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="false"
        android:orientation="vertical">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@mipmap/totary_background"
            android:orientation="vertical">
    
            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginTop="230dp">
    
                <androidx.constraintlayout.widget.ConstraintLayout
                    android:id="@+id/cl_circle"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content">
    
                    <LinearLayout
                        android:id="@+id/ll_center"
                        android:layout_width="10dp"
                        android:layout_height="10dp"
                        android:orientation="vertical"
                        app:layout_constraintLeft_toLeftOf="parent"
                        app:layout_constraintRight_toRightOf="parent"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        />
    
                    <ImageView
                        android:id="@+id/iv_circle"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        app:layout_constraintLeft_toLeftOf="parent"
                        app:layout_constraintRight_toRightOf="parent"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        android:layout_gravity="center"
                        android:src="@mipmap/rotary_circle"
                        android:visibility="visible" />
                </androidx.constraintlayout.widget.ConstraintLayout>
    
                <ImageView
                    android:id="@+id/rotary"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerHorizontal="true"
                    android:layout_gravity="center"
                    android:layout_marginTop="93dp"
                    android:src="@mipmap/rotary_pointer"
                    android:visibility="visible" />
    
                <LinearLayout
                    android:id="@+id/ll_start_rotate"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerHorizontal="true"
                    android:layout_gravity="center"
                    android:layout_marginTop="150dp"
                    android:gravity="center"
                    android:orientation="vertical">
                    <TextView
                        android:id="@+id/tv_count"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="0次机会"
                        android:textSize="11dp" />
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="抽奖"
                        android:textColor="#FF3030"
                        android:textSize="20dp" />
                </LinearLayout>
            </RelativeLayout>
    
            <FrameLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="30dp">
    
                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:background="@mipmap/box" />
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="40dp"
                    android:orientation="vertical">
                </LinearLayout>
            </FrameLayout>
    
        </LinearLayout>
    </ScrollView>
    

    动画文件:


    image.png
    <?xml version="1.0" encoding="utf-8"?>
    <rotate xmlns:android="http://schemas.android.com/apk/res/android">
        <rotate
            android:fromDegrees="0"
            android:toDegrees="359"
            android:pivotX="50%"
            android:pivotY="50%"
            android:duration="2000"
            android:repeatCount="-1">
        </rotate>
    </rotate>
    
    

    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<Int>(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实现幸运大转盘功能

          本文链接:https://www.haomeiwen.com/subject/pqrfrrtx.html