Android countdown is generally implemented as follows:
- The handler + postDelayed () method
- The Timer + TimerTask + Handler mode is used
- ScheduledExecutorService + Handler mode
- RxJava way
- CountDownTimer way
Now, with coroutines and Flow, we can use the Flow tool to implement this requirement more elegantly.
1. Rely on imports
api 'org. Jetbrains. Kotlinx: kotlinx coroutines -- core: 1.4.2'
api 'org. Jetbrains. Kotlinx: kotlinx coroutines - android: 1.4.1'
// lifecycleScope(optional)
api "Androidx. Lifecycle: lifecycle - runtime - KTX: 2.2.0." "
Copy the code
2. Code implementation
fun countDownCoroutines(
total: Int,
scope: CoroutineScope,
onTick: (Int) - >Unit,
onStart: (() -> Unit)? = null,
onFinish: (() -> Unit)? = null.): Job {
return flow {
for (i in total downTo 0) {
emit(i)
delay(1000) } }.flowOn(Dispatchers.Main) .onStart { onStart? .invoke() } .onCompletion { onFinish? .invoke() } .onEach { onTick.invoke(it) } .launchIn(scope) }Copy the code
2.1 use:
private var mCountdownJob: Job? = null
mBinding.btnStart.setOnClickListener {
mCountdownJob = countDownCoroutines(60, lifecycleScope,
onTick = { second ->
mBinding.text.text = "${second}Resend after s"
}, onStart = {
// The countdown begins
}, onFinish = {
// When the countdown ends, reset the status
mBinding.text.text = "Send verification code"
})
}
mBinding.btnStop.setOnClickListener {
// Cancel the countdownmCountdownJob? .cancel() }Copy the code
Other full demos github.com/dahui888/ko…