LiveData 没有观察具有共享视图模型的子视图页面片段
Posted
技术标签:
【中文标题】LiveData 没有观察具有共享视图模型的子视图页面片段【英文标题】:LiveData is not observing on child viewpager fragments having a shared viewmodel 【发布时间】:2021-10-10 04:26:46 【问题描述】:LiveData 不会观察子 viewpager 片段,其中子片段具有一个共享视图模型来访问数据。
这里 FragmentA 和 FragmentB 是 viewpager 的一部分,它们都共享一个 viemodel SharedViewModel。
public class SharedViewModel extends androidViewModel //in Java
private final MutableLiveData<Data> mLiveData = new MutableLiveData<>();
public LiveData<Data> getLiveData()
return mLiveData;
//for updating data through LiveData, using post as and when I get the response from DataSource as shown below.
mLiveData.postValue(response); //getting the response on debugging
class FragmentA : Fragment() //in Kotlin
override fun onCreate(@Nullable savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
mViewModel = ViewModelProvider(this).get(SharedViewModel::class.java)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View
....
mViewModel.liveData.observe(viewLifecycleOwner,
//no call coming in this block so unable to update view
)
class FragmentB : Fragment() //in Kotlin
override fun onCreate(@Nullable savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
mViewModel = ViewModelProvider(this).get(SharedViewModel::class.java)
需要一些帮助来了解为什么实时数据无法观察到变化。
提前致谢。
【问题讨论】:
【参考方案1】:您的 ViewModel 未共享。您已将其命名为 sharedViewmodel,但您通过传递 Unique Owner 获取它的实例的方式也将是一个 unique instance。
共享视图模型的正确方式是
class SharedViewModel : ViewModel()
private val myLiveData = MutableLiveData<Data>()
fun getMyLiveDta():LiveData
return myLiveData
现在在第一个片段中
class MasterFragment : Fragment()
private lateinit var itemSelector: Selector
// Get instance of viewmodel in fragment like this
private val model: SharedViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
super.onViewCreated(view, savedInstanceState)
在这样的第二个片段中
class DetailFragment : Fragment()
private val model: SharedViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
super.onViewCreated(view, savedInstanceState)
model.selected.observe(viewLifecycleOwner, Observer<Item> item ->
// Update the UI
)
【讨论】:
谢谢MRamzan。使用 ViewModel 初始化的活动范围有助于解决该问题。子片段是 viewpager 的一部分,它本身就是父片段的一部分。我可以有父片段范围而不是活动范围吗? 在您的父片段中,如果您使用 Activity 范围,您可能会遇到内存泄漏,因为在父 Activity 处于活动状态之前,您的 ViewModel 也将可用。 在观察嵌套片段中的数据时,使用 activity 或 getactivity() 代替 viewLifecycleOwner。以上是关于LiveData 没有观察具有共享视图模型的子视图页面片段的主要内容,如果未能解决你的问题,请参考以下文章
Android LiveData防止在观察时接收到最后一个值
在 Android 视图模型中的内部网络更改回调时 LiveData 未触发 - Kotlin