在这种情况下,LiveData 是如何工作的?
How does LiveData works in this case?
首先,我不是在寻求这个问题的解决方案(代码),我是在要求更正我对 LiveData 的理解,因为我认为我遗漏了什么。
据我所知,LiveData 的 onActive 函数在每次观察者 (LifeCycleOwner) 激活时触发,长话短说,在 Activity 或 Fragment 的 onCreate 方法中。
这是我现在正在处理的问题。
我正在使用 Android 导航组件,我有一个包含导航图的 Activity A,在这个图中,两个片段共享共同的逻辑,因此,我没有创建用于相互通信的接口,而是使用 ViewModel,为简单起见,我们将其称为 ActivityAViewModel。
现在,此 VM 包含以下内容。
- 此 VM 的私有 MediatorLiveData 报告值
- 一个 public 函数 returns 这个 MediatorLiveData 作为一个 LiveData,防止 UI 控制器修改它的值
- 一个做一些工作的函数,这个工作returns一个LiveData,一个Transformation用于工作返回的LiveData,returns必要的UI数据。
- 看起来像这样:
ActivityAViewModel.kt
// Private Mediator LiveData
private val mediatorLD = MediatorLiveData<Boolean>()
// Public immutable access of the mediator LiveData
fun mediatorLD(): LiveData = mediatorLD
// Representation of what the transformation is doing.
fun doFoo() {
val workLD: LiveData<WrapperClass<Boolean>> = repository.someWork()
Transformations.map(workLD) { wrappedResult ->
mediatorLD.postValue(wrappedResult.myBoolean)
}
}
现在,两个 UI 控制器 MyFragmentB.kt 和 MyFragmentC.kt 正在观察 MutableLiveData 的 LiveData 版本,我遇到的问题是当 MyFragmentB 执行 doFoo() 时,它相应地收到结果,那里没有问题,但是当我导航到 MyFragmentC.kt 时,相同的结果会报告给 C,反之亦然。
我不希望发生这种情况,如果 FragmentB 已经观察到变化,我不希望 C 监听该变化。
我有点理解为什么会这样了。
据我所知,LiveData 的 onActive 函数在每次观察者 (LifeCycleOwner) 激活时触发,长话短说,在 Activity 或 Fragment 的 onCreate 方法中。
由于使用 postValue 检测到更改,ViewModel 正在等待其观察者处于活动状态以发送结果。
当执行到另一个片段的导航时,观察者准备就绪,触发 onActive 并检测变化。
有没有办法不让这两个片段接收到结果?我的意思是,当这两个中的一个收到结果时,另一个不会听吗?
您可能希望相应地设计此事件,与 Jeel 分享的博客 post 中讨论的事件包装器非常相似。
基本思路是 Event 只会被消耗一次。然后您可以用 LiveData 包装它。当您在 LiveData 中设置一个新事件时,观察者将收到通知,在第一次消费新事件后,后续消费不会 return 任何价值。
首先,我不是在寻求这个问题的解决方案(代码),我是在要求更正我对 LiveData 的理解,因为我认为我遗漏了什么。
据我所知,LiveData 的 onActive 函数在每次观察者 (LifeCycleOwner) 激活时触发,长话短说,在 Activity 或 Fragment 的 onCreate 方法中。
这是我现在正在处理的问题。
我正在使用 Android 导航组件,我有一个包含导航图的 Activity A,在这个图中,两个片段共享共同的逻辑,因此,我没有创建用于相互通信的接口,而是使用 ViewModel,为简单起见,我们将其称为 ActivityAViewModel。
现在,此 VM 包含以下内容。
- 此 VM 的私有 MediatorLiveData 报告值
- 一个 public 函数 returns 这个 MediatorLiveData 作为一个 LiveData,防止 UI 控制器修改它的值
- 一个做一些工作的函数,这个工作returns一个LiveData,一个Transformation用于工作返回的LiveData,returns必要的UI数据。
- 看起来像这样:
ActivityAViewModel.kt
// Private Mediator LiveData
private val mediatorLD = MediatorLiveData<Boolean>()
// Public immutable access of the mediator LiveData
fun mediatorLD(): LiveData = mediatorLD
// Representation of what the transformation is doing.
fun doFoo() {
val workLD: LiveData<WrapperClass<Boolean>> = repository.someWork()
Transformations.map(workLD) { wrappedResult ->
mediatorLD.postValue(wrappedResult.myBoolean)
}
}
现在,两个 UI 控制器 MyFragmentB.kt 和 MyFragmentC.kt 正在观察 MutableLiveData 的 LiveData 版本,我遇到的问题是当 MyFragmentB 执行 doFoo() 时,它相应地收到结果,那里没有问题,但是当我导航到 MyFragmentC.kt 时,相同的结果会报告给 C,反之亦然。
我不希望发生这种情况,如果 FragmentB 已经观察到变化,我不希望 C 监听该变化。
我有点理解为什么会这样了。
据我所知,LiveData 的 onActive 函数在每次观察者 (LifeCycleOwner) 激活时触发,长话短说,在 Activity 或 Fragment 的 onCreate 方法中。
由于使用 postValue 检测到更改,ViewModel 正在等待其观察者处于活动状态以发送结果。
当执行到另一个片段的导航时,观察者准备就绪,触发 onActive 并检测变化。
有没有办法不让这两个片段接收到结果?我的意思是,当这两个中的一个收到结果时,另一个不会听吗?
您可能希望相应地设计此事件,与 Jeel 分享的博客 post 中讨论的事件包装器非常相似。
基本思路是 Event 只会被消耗一次。然后您可以用 LiveData 包装它。当您在 LiveData 中设置一个新事件时,观察者将收到通知,在第一次消费新事件后,后续消费不会 return 任何价值。