0

我的 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

编辑:我现在注意到的是,因为我从 Fragment D 调用 setSearchText(),所以我能够观察 Fragment D 中 LiveData A 的变化,但我想在 Fragment A 中观察它但不能。我在片段 D 中有一个搜索栏,底部有一个带有 3 个片段的视图寻呼机,所有 4 个片段都有一个共同的 viewModel,我在这里做错了什么,或者这不是实现这个的方法吗?TIA

4

2 回答 2

1

终于找到了根本原因,问题是viewModel在每个fragment中都有自己的生命周期所有者,解决方法是viewModel在fragment的父activity中声明并初始化对象,并使用它在fragment中的instace来观察LiveData

于 2020-06-16T11:18:51.950 回答
0

问题是:

你的extractA功能

val a: LiveData<List<A>> = Transformations.map(_searchText, ::extractA)

只会在_searchTextwill 的值改变时执行。

这就是Transformations工作方式,只要值发生变化,它们就会应用给定的函数。

于 2020-06-15T22:39:41.713 回答