本文原始发表于:https://juejin.cn/post/6955727941850365965
LiveData 默认是支持粘性消息的(关于什么是粘性消息,请移步我的另一篇文章:LiveData 的正确使用姿势以及反模式 ),如何通过 LiveData 来实现非粘性消息呢,本文将在官博的基础上,分析几种尝试的方案,以及他们各自的优缺点
姿势一:重置 LiveData 的值
在 observer 里加上一个判断,当 LiveData 的值符合某个条件的时候,才做出响应的更新 UI 逻辑,然后提供一个重置 LiveData 值的方法,重置之后,observer 中条件判断为 fasle,因此可以达到不更新 UI 的目的
示例代码
moneyReceivedViewModel.billLiveData.observe(this, Observer {
if (it != null) {
Toast.makeText(this, "到账$it元", Toast.LENGTH_SHORT).show()
}
})
class MoneyReceivedViewModel : ViewModel {
private val _billLiveData = MutableLiveData<String>()
val billLiveData: LiveData<String> = _billLiveData
// 在 observe 之前和 show Toast 之后重置一下 LiveData
fun reset() {
_billLiveData.value = null
}
}
缺陷:
- 需要在 observer 中增加一些逻辑判断代码,这不符合简洁的 MVVM 模式(不应该在 View 层做过多的逻辑处理)
- 需要手动重置,不够优雅,一旦忘记重置就容易引发问题
姿势二:使用 SingleLiveEvent
SingleLiveEvent 是官方 sample 中封装的 LiveData,可以实现一个事件只被消费一,实现原理也很简单
class SingleLiveEvent<T> : MutableLiveData<T>() {
private val mPending: AtomicBoolean = AtomicBoolean(false)
@MainThread
override fun