如何使用Kotlin Coroutines将setOnClickListener反弹1秒钟? [英] How can I debounce a setOnClickListener for 1 second using Kotlin Coroutines?
问题描述
当用户快速点击按钮时,showDialog()方法会在彼此之上多次显示,因此当您关闭它时,它后面还会再显示一次.我正在寻找一种在不使用处理程序的情况下忽略第二次轻按1秒钟或检查上一次轻按的时间的方法.
When user taps fast on the button the showDialog() method displays multiple times on top of each other, so when you dismiss it there is another one behind it. I am looking for a way to ignore the second tap for 1 second without using a handler or check the previous tap's time.
//Button that opens a dialog
button.setOnClickListener {
showDialog()
}
我正在寻找使用Kotlin协程或Kotlin流程的解决方案,以用于将来的实现.
I am looking for a solution using Kotlin coroutines or Kotlin flows for future implementations.
推荐答案
为此,最好使用简单的 Flag ,而不要延迟,因为这不是良好的用户体验.
It's better to use a simple Flag for that instead of delay as it's not a good user experience.
但是,如果您想使用协同程序,则可以简单地使用科特琳·协程的流程适用于此:
But if you want to use Coroutines, You can simply use Kotlin Coroutine's Flow to apply this:
首先,我为点击事件创建了一个扩展功能,该事件返回了协程的流程.像这样:
First I created an Extension Function for the click event that returns a Coroutine's Flow. like this:
fun View.clicks(): Flow<Unit> = callbackFlow {
setOnClickListener {
offer(Unit)
}
awaitClose { setOnClickListener(null) }
}
现在,您所需要做的就是像这样在 onCreate 中调用函数:
Now, All you need is Calling your Function in onCreate like this:
button.clicks().debounce(1000).onEach { println("clicked") }.launchIn(GlobalScope)
别忘了在build.gradle文件中添加以下行:
Don't forget to add these lines in build.gradle file:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
throttleFirst 运算符的Flow类似物尚未在kotlin协程中实现.但是,可以借助扩展功能来实现:
The Flow analogue of throttleFirst operator is not implemented yet in kotlin coroutines. however, can be implemented with the help of Extension Functions:
@FlowPreview
@ExperimentalCoroutinesApi
fun <T> Flow<T>.throttleFirst(windowDuration: Long): Flow<T> = flow {
var lastEmissionTime = 0L
collect { upstream ->
val currentTime = System.currentTimeMillis()
val mayEmit = currentTime - lastEmissionTime > windowDuration
if (mayEmit)
{
lastEmissionTime = currentTime
emit(upstream)
}
}
}
更改如下:
binding.button.clicks().throttleFirst(1250)
.onEach {
//delay(100)
showDialog()
}.launchIn(GlobalScope)
此外,您可以使用delay()处理此问题.轻松根据需要更改这些参数的值.
Also, you can use a delay() to handle this. Take it easy to change value of these parameters according to your needs.
这篇关于如何使用Kotlin Coroutines将setOnClickListener反弹1秒钟?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!