在一种特定情况下未观察到 LiveData
LiveData is not getting observed for one specific scenario
我的 ViewModel 中有 3 个 LiveData 对象,我正在对它们应用转换,问题是 2 个 LiveData 被观察到而另一个没有,我尝试了不同的解决方案,例如更改 ViewModel 的初始化方式或者 LiveData 的初始化方式,但对我没有任何作用。
class MyClass : ViewModel() {
init {
_originallist.value = Instance.getOrignalList()
}
// observed in Fragment A
val a: LiveData<List<A>> = Transformations.map(_searchText, ::extractA)
// observed in Fragment B
val b: LiveData<List<B>> = Transformations.map(_originallist, ::extractB)
// observed in Fragment C
val c: LiveData<List<C>> = Transformations.map(_originalList, ::extractC)
// Called from Fragment D to change the _searchText liveData
fun setSearchText(text: String) {
_searchText.value = text
}
fun extractA(text: String): List<A> {
val temp = ArrayList<A>()
list.foreach {
if (it.contains(text, false) temp . add (it)
}
return temp
}
fun extractB(list: List<B>): List<B> {
// do something
}
fun extractC(list: List<C>): List<C> {
// do something
}
}
如果您注意到 LiveData b 和 c 只初始化一次,因此我可以在我的 RecyclerView 中看到数据,但对于 LiveData A,搜索文本可以根据用户输入更改,这是我的片段没有观察到这个实时数据的地方。
注意事项:这是我的 3 个 viewPager 片段的通用 ViewModel,在一个片段中观察到 LiveData a,在另一个片段中观察到 B,在另一个片段中观察到 C。
最后,我还必须对其他 2 个片段进行搜索。
当我调试我的片段中的观察者行时,我想指出的另一件事是所有 3 个片段中的代码都是相同的,只是它们观察的是不同的 LiveData
编辑:我现在注意到的是,因为我从片段 D 调用 setSearchText(),所以我能够观察片段 D 中 LiveData A 的变化,但我想在片段 A 中观察它但不能。
我在片段 D 和底部有一个搜索栏,我有一个包含 3 个片段的视图寻呼机,所有 4 个片段都有一个共同的 viewModel,我在这里做错了什么,或者这不是实现这个的方法吗?
TIA
问题是:
你的函数 extractA
在
val a: LiveData<List<A>> = Transformations.map(_searchText, ::extractA)
只有在_searchText
的值发生变化时才会执行
这就是 Transformations
的工作方式,只要值发生变化,它们就会应用给定的函数。
终于找到了根本原因,问题是 viewModel
在每个片段中都有自己的生命周期所有者,解决这个问题的方法是声明并初始化 viewModel
对象片段的父 activity 并在片段中使用其实例来观察 LiveData
我的 ViewModel 中有 3 个 LiveData 对象,我正在对它们应用转换,问题是 2 个 LiveData 被观察到而另一个没有,我尝试了不同的解决方案,例如更改 ViewModel 的初始化方式或者 LiveData 的初始化方式,但对我没有任何作用。
class MyClass : ViewModel() {
init {
_originallist.value = Instance.getOrignalList()
}
// observed in Fragment A
val a: LiveData<List<A>> = Transformations.map(_searchText, ::extractA)
// observed in Fragment B
val b: LiveData<List<B>> = Transformations.map(_originallist, ::extractB)
// observed in Fragment C
val c: LiveData<List<C>> = Transformations.map(_originalList, ::extractC)
// Called from Fragment D to change the _searchText liveData
fun setSearchText(text: String) {
_searchText.value = text
}
fun extractA(text: String): List<A> {
val temp = ArrayList<A>()
list.foreach {
if (it.contains(text, false) temp . add (it)
}
return temp
}
fun extractB(list: List<B>): List<B> {
// do something
}
fun extractC(list: List<C>): List<C> {
// do something
}
}
如果您注意到 LiveData b 和 c 只初始化一次,因此我可以在我的 RecyclerView 中看到数据,但对于 LiveData A,搜索文本可以根据用户输入更改,这是我的片段没有观察到这个实时数据的地方。 注意事项:这是我的 3 个 viewPager 片段的通用 ViewModel,在一个片段中观察到 LiveData a,在另一个片段中观察到 B,在另一个片段中观察到 C。 最后,我还必须对其他 2 个片段进行搜索。 当我调试我的片段中的观察者行时,我想指出的另一件事是所有 3 个片段中的代码都是相同的,只是它们观察的是不同的 LiveData
编辑:我现在注意到的是,因为我从片段 D 调用 setSearchText(),所以我能够观察片段 D 中 LiveData A 的变化,但我想在片段 A 中观察它但不能。 我在片段 D 和底部有一个搜索栏,我有一个包含 3 个片段的视图寻呼机,所有 4 个片段都有一个共同的 viewModel,我在这里做错了什么,或者这不是实现这个的方法吗? TIA
问题是:
你的函数 extractA
在
val a: LiveData<List<A>> = Transformations.map(_searchText, ::extractA)
只有在_searchText
的值发生变化时才会执行
这就是 Transformations
的工作方式,只要值发生变化,它们就会应用给定的函数。
终于找到了根本原因,问题是 viewModel
在每个片段中都有自己的生命周期所有者,解决这个问题的方法是声明并初始化 viewModel
对象片段的父 activity 并在片段中使用其实例来观察 LiveData