gpt4 book ai didi

android - 如何避免 MediatorLiveData 的所有源调用同一函数?

转载 作者:行者123 更新时间:2023-12-05 00:16:37 34 4
gpt4 key购买 nike

问题简介:当使用 android 随 android jetpack 添加的 MediatorLiveData 时,我发现自己经常从各个来源调用相同的函数。例如,这可能是因为,每当更新源时,我都必须检查它是否有影响,或者另一个源是否更重要。代码示例(Kotlin,但不重要):

val isHovered = MutableLiveData<Boolean>()
val isSelected = MutableLiveData<Boolean>()

val color = MediatorLiveData<Int>().apply {
addSource(isHovered) { updateColor() }
addSource(isSelected) { updateColor() }
}

fun updateColor() {
if (isHovered.value == true)
color.value = Color.GREEN
else if (isSelected.value == true)
color.value = Color.RED
else
color.value = Color.GRAY
}

项目悬停时为绿色,选择且未悬停时为红色,否则为灰色。当 isSelected 更改为 true 时,在将颜色更改为红色之前,我仍然需要检查它是否悬停。另外,当 isHovering 更改为 false 时,我需要在将颜色更改为灰色之前检查它是否被选中。因此,最简单的是一个函数,它考虑所有变量并相应地设置颜色。

我的问题:当 MediatorLiveData 从非 Activity 状态更改为 Activity 状态时,由于 View 移至前台,因此可能会针对每个发生更改的源多次调用函数 updateColor。这是不必要的,因为每次调用都已经考虑了所有变量。由于此函数可能非常复杂并且可能有很多源,有没有办法避免对源 LiveDatas 的相同状态多次调用它?

最佳答案

我遇到了同样的问题并提出了以下解决方案。首先,将所有来源的值收集到一个值:

data class State(val isHovered: Boolean, val isSelected: Boolean)

private val state = MediatorLiveData<State>().apply {
fun update() {
value = State(isHovered.value ?: false, isSelected.value ?: false)
}

addSource(isHovered) { update() }
addSource(isSelected) { update() }
}

然后我创建了一个扩展函数来仅发出不同的值

fun <T> LiveData<T>.distinct(): LiveData<T> = MediatorLiveData<T>().apply {
var wasSet = false
addSource(this@distinct) {
// Update value if it has been changed or it's the first time the method called
// Because value is null by default it will not be set to null again, leaving the live data in [value not set] state
if (value != it || !wasSet) {
value = it
wasSet = true
}
}
}

因此,当观察 state.distinct() 时,只有当它真正发生变化时,您才会获得更新的值。

有时另一个扩展也可能有用:

fun <T> LiveData<T>.squashUpdates() = MediatorLiveData<T>().apply {
addSource(this@squashUpdates) {
postValue(it)
}
}

通常,当 LiveData 值发生更改时,它会立即通知同一堆栈帧中的所有观察者。假设您有一个 MediatorLiveData 并更改多个源的值,例如:

isHovered.value = true
isSelected.value = true

state值将连续改变两次State(true, false)State(true, true)。即使使用上面的 distinct ,它们都会被调度,因为值实际上是不同的。在这种情况下,squashUpdates 通过延迟调度到堆栈帧的末尾、仅调度最后一个值来提供帮助。

关于android - 如何避免 MediatorLiveData 的所有源调用同一函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57256018/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com