如何在三个不同的 Fragment 上观察来自实时数据 android 的数据

How to observe data from live data android on Three different Fragment

我有我的 Activity MainActivity.kt .

还有一个 ViewModel MainActivityViewModel.kt

我想观察我的 3 个不同片段的实时数据。

class MainActivity{
      
      lateinit var mainActivityViewModel: MainActivityViewModel
      ...

     mainActivityViewModel = ViewModelProviders.of(this, viewModelFactory).get(MainActivityViewModel::class.java)
}

class MainFragmentOne{
      
      lateinit var mainActivityViewModel: MainActivityViewModel
      ...

     mainActivityViewModel = ViewModelProviders.of(this, viewModelFactory).get(MainActivityViewModel::class.java)
}

但我的观察者只在 activity 上工作,不在片段上工作。

嘿,除了在你的片段 class.

中你应该使用 requireActivity() 而不是这一点之外,你所做的一切都很棒

确保您的所有片段都附加到您的 viewModel 控股 Activity。

class MainActivity{

      lateinit var mainActivityViewModel: MainActivityViewModel
      ...

     mainActivityViewModel = ViewModelProviders.of(this, viewModelFactory).get(MainActivityViewModel::class.java)
}

class MainFragmentOne{

      lateinit var mainActivityViewModel: MainActivityViewModel
      ...

     mainActivityViewModel = ViewModelProviders.of(requireActivity(), viewModelFactory).get(MainActivityViewModel::class.java)
}

这将帮助您解决问题。

更多详细信息view这个。

ViewModelProviders.of 有 2 个不同的构造函数:

of(Fragment fragment, ViewModelProvider.Factory factory)

Creates a ViewModelProvider, which retains ViewModels while a scope of given fragment is alive.

of(FragmentActivity activity, ViewModelProvider.Factory factory)

Creates a ViewModelProvider, which retains ViewModels while a scope of given Activity is alive.

基本上,当您使用 this 作为 activity 中的第一个参数时,您传递了 activity 的上下文并创建了一个视图模型在 activity 的范围内还活着,但是你的第二个 this 是你片段的上下文,这意味着只要你的片段还活着,第二个 ViewModel 就会活着(仅一个片段)。

您应该在片段中使用 activity 的上下文,因为附加和交换片段时 activity 始终处于活动状态。您应该将片段更改为:

class MainFragmentOne{

      lateinit var mainActivityViewModel: MainActivityViewModel
      ...

     mainActivityViewModel = ViewModelProviders.of(activity!!, viewModelFactory).get(MainActivityViewModel::class.java)
}

或者您可以使用上一个答案中的 requireActivity() 方法。

要实现您的目标,您需要三件事。 activity/fragment 将 post 值赋给 ViewModelViewModel 和 activity/fragment 将从 ViewModel 检索数据。假设您的数据存储在 ArrayList 中,并且您想从不同的片段中更新和检索它。
首先,我们必须实现一个ViewModel。它包含您想要在 activities/fragments 之间共享的数据。您将 MutableLiveData 声明为 ArrayList 然后对其进行初始化。

class testviewmodel : ViewModel() {
    val list: MutableLiveData<ArrayList<String>> = MutableLiveData()
    init {
        list.value = arrayListOf()
    }
}

我们的下一步是使用您的 activity:

访问和更新 ArrayList
    val viewmodel = ViewModelProviders.of(this).get(testviewmodel::class.java)
    // update the array in Viewmodel
    viewmodel.list.postValue(yourarray)

如果您使用 Fragment 更新它,请使用:

    activity?.let {
        val viewmodel = ViewModelProviders.of(it).get(testviewmodel::class.java)
         // update the array in Viewmodel
        viewmodel.list.postValue(yourarray)
    }

最后,要从片段中的 ViewModel 检索数据,请将其放入您的 onViewCreated:

activity?.let {
    val viewmodel = ViewModelProviders.of(it).get(Dbviewmodel::class.java)
    observeInput(viewmodel)
}

把这个放在你的 onViewCreated 之外:

private fun observeInput(viewmodel: testviewmodel ) {

    viewmodel.list.observe(viewLifecycleOwner, Observer {
        it?.let {
            if (it.size > 5) {
                pos = it[5]
//grab it
                Toast.makeText(context,pos,Toast.LENGTH_LONG).show()
//display grabbed data
            }
        }
    })
}

查看此 docs 了解有关 ViewModels
的更多信息 祝你好运!我希望这会有所帮助:)

那是因为您使用的是片段 'this' 实例,而不是 activity。

替换

mainActivityViewModel = ViewModelProviders.of(this, viewModelFactory).get(MainActivityViewModel::class.java)

activity?.let { mainActivityViewModel = ViewModelProviders.of(it, viewModelFactory).get(MainActivityViewModel::class.java) }