首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Kotlin Android去反弹版

Kotlin Android去反弹版
EN

Stack Overflow用户
提问于 2018-06-14 21:27:47
回答 9查看 29.9K关注 0票数 36

有没有什么奇妙的方法可以用Kotlin Android实现debounce逻辑?

我没有在项目中使用Rx。

Java中有一种方法,但是它对我来说太大了。

EN

回答 9

Stack Overflow用户

发布于 2019-07-29 19:22:39

我已经创建了一个带有三个去反弹运算符的gist,灵感来自Patrick中的this elegant solution,我在其中添加了两个类似的案例:throttleFirstthrottleLatest。这两个都与他们的RxJava类似物(throttleFirstthrottleLatest)非常相似。

throttleLatest的工作方式类似于debounce,但它按时间间隔操作,并返回每个时间间隔的最新数据,这允许您在需要时获取和处理中间数据。

fun <T> throttleLatest(
    intervalMs: Long = 300L,
    coroutineScope: CoroutineScope,
    destinationFunction: (T) -> Unit
): (T) -> Unit {
    var throttleJob: Job? = null
    var latestParam: T
    return { param: T ->
        latestParam = param
        if (throttleJob?.isCompleted != false) {
            throttleJob = coroutineScope.launch {
                delay(intervalMs)
                latestParam.let(destinationFunction)
            }
        }
    }
}

当您需要立即处理第一个调用,然后跳过后续调用一段时间以避免不受欢迎的行为时(例如,避免在安卓上启动两个相同的活动),throttleFirst非常有用。

fun <T> throttleFirst(
    skipMs: Long = 300L,
    coroutineScope: CoroutineScope,
    destinationFunction: (T) -> Unit
): (T) -> Unit {
    var throttleJob: Job? = null
    return { param: T ->
        if (throttleJob?.isCompleted != false) {
            throttleJob = coroutineScope.launch {
                destinationFunction(param)
                delay(skipMs)
            }
        }
    }
}

debounce有助于检测一段时间内未提交新数据时的状态,从而有效地允许您在输入完成时处理数据。

fun <T> debounce(
    waitMs: Long = 300L,
    coroutineScope: CoroutineScope,
    destinationFunction: (T) -> Unit
): (T) -> Unit {
    var debounceJob: Job? = null
    return { param: T ->
        debounceJob?.cancel()
        debounceJob = coroutineScope.launch {
            delay(waitMs)
            destinationFunction(param)
        }
    }
}

所有这些运算符都可以按如下方式使用:

val onEmailChange: (String) -> Unit = throttleLatest(
            300L, 
            viewLifecycleOwner.lifecycleScope, 
            viewModel::onEmailChanged
        )
emailView.onTextChanged(onEmailChange)
票数 36
EN

Stack Overflow用户

发布于 2020-10-25 07:37:10

对于从ViewModel内部执行的一种简单方法,您可以在viewModelScope中启动一个作业,跟踪该作业,如果在作业完成之前出现新值,则取消该作业:

private var searchJob: Job? = null

fun searchDebounced(searchText: String) {
    searchJob?.cancel()
    searchJob = viewModelScope.launch {
        delay(500)
        search(searchText)
    }
}
票数 22
EN

Stack Overflow用户

发布于 2020-02-25 11:05:33

我使用来自Kotlin CoroutinescallbackFlowdebounce来实现去抖动。例如,要实现按钮单击事件的去抖动,请执行以下操作:

Button上创建扩展方法以生成callbackFlow

fun Button.onClicked() = callbackFlow<Unit> {
    setOnClickListener { offer(Unit) }
    awaitClose { setOnClickListener(null) }
}

订阅生命周期感知活动或片段中的事件。下面的代码片段每隔250ms揭开点击事件的面纱:

buttonFoo
    .onClicked()
    .debounce(250)
    .onEach { doSomethingRadical() }
    .launchIn(lifecycleScope)
票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50858684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档