1、倒计时工具类:
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() }//like java finally
.onEach { onTick.invoke(it) }
.launchIn(scope)
}
fun countDownDelayCoroutines(
total: Int,
delayTimeMillis: Long,
scope: CoroutineScope,
onTick: (Int) -> Unit,
onStart: (() -> Unit)? = null,
onFinish: (() -> Unit)? = null,
): Job {
return flow {
for (i in total downTo 0) {
emit(i)
delay(delayTimeMillis)
}
}
.flowOn(Dispatchers.Main)
.onStart { onStart?.invoke() }
.onCompletion { onFinish?.invoke() }//like java finally
.onEach { onTick.invoke(it) }
.launchIn(scope)
}
/**
* 倒计时的实现
*/
fun FragmentActivity.countDown(
time: Int = 5,
start: (scop: CoroutineScope) -> Unit={},
end: () -> Unit={},
next: (time: Int) -> Unit={},
delayTimeMillis: Long?=1000
) {
lifecycleScope.launch {
// 在这个范围内启动的协程会在Lifecycle被销毁的时候自动取消
flow {
(time downTo 0).forEach {
delayTimeMillis?.let { it1 -> delay(it1) }
emit(it)
}
}.onStart {
// 倒计时开始 ,在这里可以让Button 禁止点击状态
start(this@launch)
}.onCompletion {
// 倒计时结束 ,在这里可以让Button 恢复点击状态
end()
}.catch {
//错误
LogUtil.e(it.message ?: "Unkown Error")
}.collect {
// 在这里 更新值来显示到UI
next(it)
}
}
}
2、调用,60秒倒计时
countDownCoroutines(60, lifecycleScope, onTick = {
getCodeTx.isEnabled = false
mBinding.getCodeTx.apply {
text = getString(R.string.login_code_count_time, it.plus(0).toString())
text.apply {
text = toClickSpan(
it.plus(0).toString().length + 1..text.toString().length,
color = getColorRes(R.color.login_send_code_normal)
) {}
movementMethod = LinkMovementMethod.getInstance()
highlightColor = Color.TRANSPARENT
}
}
}) {
getCodeTx.text = getString(R.string.login_text_reset_code)
getCodeTx.isEnabled = true
}