【Android】自定义倒计时弹框(Handler/Timer/RxJava/持续更新)

自定义倒计时弹框,升级版,三个方法

效果图

一个示例
在这里插入图片描述

主要的实现方法

在这篇文章中,你将学会

  1. 如何使用Handler进行倒计时
  2. 如何使用CountDownTimer进行倒计时
  3. 如何使用RxJava的internal实现倒计时
  4. 最后举个倒计时弹框的栗子,活学活用,mozhimen~

  • Handler来实现
private var countDownTime = 10
private var countDownHandler = Handler(Looper.getMainLooper())
private val countDown = object : Runnable {
    override fun run() {
        if (countDownTime >= 0) {
            countDownHandler.postDelayed(this, 1000)//每秒
            //执行UI更新逻辑
         	//textCountDown.text = "${countDownTime}s"
         } else {
            //停止的逻辑
			countDownHandler.removeCallbacksAndMessages(null)
        	//countDownDialog.dismiss()
        }
    	countDownTime--
	}
}

//调用
countDownTime = 10
countDownHandler.postDelayed(countDown, 0)
  • CountDownTimer实现
private var countDownTime = 10
private val countDownTimer: CountDownTimer = object : CountDownTimer(countDownTime.toLong() * 1000, 1000) {
	@SuppressLint("SetTextI18n")
    override fun onTick(millisUntilFinished: Long) {
    	//执行UI更新逻辑
    	//textCountDown.text = "${millisUntilFinished / 1000}s"
	}

    override fun onFinish() {
    	//停止的逻辑
    	//countDownDialog.dismiss()
	}
}

//调用
countDownTimer.start()
  • RxJava实现
private var countDownTime = 10
private val disposables = CompositeDisposable()
disposables.add(Flowable.intervalRange(0, countDownTime , 0, 1, TimeUnit.SECONDS)
	.observeOn(Schedulers.io())
	.doOnNext {
		//执行UI更新逻辑
		//textCountDown.text = "${countDownTime-1}s"
	}
	.doOnComplete {
		//停止的逻辑
		//countDownDialog.dismiss()
		countDownTime = 10
    }
	.subscribe())

结合所学,我们来实现一下

kotlin

class CountDownOrderDialog : Dialog {
    constructor(context: Context?) : super(context!!)
    constructor(context: Context?, theme: Int) : super(context!!, theme)

    interface IGetExitActionCallback {
        fun setExitAction()
    }

    enum class OrderResult(val value: String) {
        SUCCESS("微信扫码参会人员邀请"),
        FAIL("预约失败")
    }

    class Builder(private val context: Context) {
        private lateinit var countDownDialog: CountDownOrderDialog

        private var countDownTime = 10
        private var countDownHandler = Handler(Looper.getMainLooper())
        private val countDown = object : Runnable {
            override fun run() {
                if (countDownTime >= 0) {
                    countDownHandler.postDelayed(this, 1000)//每秒
                    //执行UI更新逻辑
                    textCountDown.text = "${countDownTime}s"
                } else {
                    //停止的逻辑
                    countDownHandler.removeCallbacksAndMessages(null)
                    iGetExitActionCallback?.setExitAction()
                    countDownDialog.dismiss()
                }
                countDownTime--
            }
        }

        private var orderResult: OrderResult? = null
        private var mTheme: String? = null
        private var mName: String? = null
        private var mTime: String? = null
        private var mQRImage: Drawable? = null
        private var positiveButtonClickListener: DialogInterface.OnClickListener? = null
        private var iGetExitActionCallback: IGetExitActionCallback? = null

        //设置属性
        fun setOrderResult(orderResult: OrderResult): Builder {
            this.orderResult = orderResult
            return this
        }

        //设置会议室文本
        fun setName(name: String): Builder {
            this.mName = name
            return this
        }

        //设置主题
        fun setTheme(theme: String): Builder {
            this.mTheme = theme
            return this
        }

        //设置时间
        fun setTime(time: String): Builder {
            this.mTime = time
            return this
        }

        //设置二维码图标
        fun setQRImage(qrImage: Drawable): Builder {
            this.mQRImage = qrImage
            return this
        }

        //设置退出点击事件
        fun setPositiveButton(listener: DialogInterface.OnClickListener): Builder {
            this.positiveButtonClickListener = listener
            return this
        }

        fun setExitAction(iGetExitActionCallback: IGetExitActionCallback): Builder {
            this.iGetExitActionCallback = iGetExitActionCallback
            return this
        }

        private lateinit var textCountDown: TextView
        private lateinit var dialogPane1: FrameLayout
        private lateinit var dialogPane2: LinearLayout
        private lateinit var dialogPane3: LinearLayout
        private lateinit var dialogFail: TextView
        private lateinit var dialogTitle: TextView
        private lateinit var dialogTheme: TextView
        private lateinit var dialogName: TextView
        private lateinit var dialogTime: TextView
        private lateinit var dialogQr: ImageView

        fun create(): CountDownOrderDialog {
            val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            //为自定义弹框设置主题
            countDownDialog = CountDownOrderDialog(context, R.style.CustomDialog)
            val view = layoutInflater.inflate(R.layout.dialog_champer_order, null)
            countDownDialog.addContentView(view, LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.MATCH_PARENT
            ))

            //设置倒计时
            textCountDown = view.findViewById(R.id.dialog_champer_countdown)
            textCountDown.text = "10s"

            dialogPane1 = view.findViewById(R.id.dialog_champer_order_pane1)
            dialogPane2 = view.findViewById(R.id.dialog_champer_order_pane2)
            dialogPane3 = view.findViewById(R.id.dialog_champer_order_pane3)
            dialogFail = view.findViewById(R.id.dialog_champer_order_fail)
            dialogTitle = view.findViewById(R.id.dialog_champer_order_title)
            dialogTheme = view.findViewById(R.id.dialog_champer_order_theme)
            dialogName = view.findViewById(R.id.dialog_champer_order_name)
            dialogTime = view.findViewById(R.id.dialog_champer_order_time)
            dialogQr = view.findViewById(R.id.dialog_champer_order_qr)

            orderResult?.let {
                setPaneStyle(it)
            } ?: kotlin.run {
                setPaneStyle(OrderResult.FAIL)
            }

            //设置弹框按钮
            positiveButtonClickListener?.let {
                (view.findViewById(R.id.dialog_champer_order_close) as Button).setOnClickListener {
                    countDownHandler.removeCallbacksAndMessages(null)
                    positiveButtonClickListener!!.onClick(countDownDialog, DialogInterface.BUTTON_POSITIVE)
                    iGetExitActionCallback?.setExitAction()
                }
            } ?: run {
                (view.findViewById(R.id.dialog_champer_order_close) as Button).visibility = View.GONE
            }

            countDownDialog.setContentView(view)
            countDownTime = 10
            countDownHandler.postDelayed(countDown, 0)
            return countDownDialog
        }

        private fun setPaneStyle(orderResult: OrderResult) {
            when (orderResult) {
                OrderResult.SUCCESS -> {
                    dialogPane1.visibility = View.VISIBLE
                    dialogPane2.visibility = View.VISIBLE
                    dialogPane3.visibility = View.VISIBLE
                    dialogFail.visibility = View.GONE

                    //设置标题
                    dialogTitle.text = orderResult.value

                    //设置名称
                    mName?.let {
                        dialogName.text = it
                    }

                    //设置主题
                    mTheme?.let {
                        dialogTheme.text = it
                    }

                    //设置时间
                    mTime?.let {
                        dialogTime.text = it
                    }

                    //设置二维码图标
                    mQRImage?.let {
                        dialogQr.setImageDrawable(it)
                        dialogQr.visibility = View.VISIBLE
                    } ?: kotlin.run {
                        dialogQr.visibility = View.GONE
                        dialogQr.visibility = View.GONE
                    }
                }
                else -> {
                    dialogPane1.visibility = View.GONE
                    dialogPane2.visibility = View.GONE
                    dialogPane3.visibility = View.GONE
                    dialogFail.visibility = View.VISIBLE
                    dialogFail.text=orderResult.value
                }
            }
        }
    }
}

如何调用

val builder = CountDownOrderDialog.Builder(this)
builder.apply {
	setOrderResult(CountDownOrderDialog.OrderResult.SUCCESS)
	setTheme("技术选型会")
	setName("赵的会议")
	setTime("08:00-09:00")
	setPositiveButton(DialogInterface.OnClickListener { dialog, _ ->
		dialog.dismiss()
	})
	setExitAction(object : CountDownOrderDialog.IGetExitActionCallback {
		override fun setExitAction() {
			//新增回调功能,执行倒计时退出后的逻辑
		}
	})
}

上文只是通过Handler的方式来实现,接下来用这个例子试试刚才学习的成果,其他的方法就交给你啦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mozhimen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值