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

时间:2019-08-28 16:40:49

标签: android kotlin android-lifecycle android-livedata mutablelivedata

嘿,我有我的活动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)
}

但是我的观察者只从事活动而不是碎片。

4 个答案:

答案 0 :(得分:1)

嘿,除了在片段类中应该使用requireActivity()之外,您正在做其他所有事情。

确保将所有片段都附加到viewModel持有活动上。

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

答案 1 :(得分:1)

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

of(Fragment fragment, ViewModelProvider.Factory factory)
  

创建一个ViewModelProvider,它保留ViewModel,而范围为   给定的片段还活着。

of(FragmentActivity activity, ViewModelProvider.Factory factory)
  

创建一个ViewModelProvider,它保留ViewModel,而范围为   给定的活动还活着。

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

相反,您应该在片段中执行的操作是使用活动的上下文,因为在附加和交换片段时活动始终是活动的。您应该将片段更改为:

class MainFragmentOne{

      lateinit var mainActivityViewModel: MainActivityViewModel
      ...

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

或者您可以使用先前答案的requireActivity()方法。

答案 2 :(得分:1)

要实现您想做的事情,您需要三件事。活动/片段将把值发布到ViewModelViewModel,以及活动/片段将从ViewModel检索数据。假设您的数据存储在ArrayList中,并且您想从不同的片段中进行更新和检索。
首先,我们必须实现ViewModel。它包含您要在活动/片段之间共享的数据。您将MutableLiveData声明为ArrayList,然后对其进行初始化。

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

我们的下一步是使用您的活动访问和更新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的更多信息
祝好运!我希望这会有所帮助:)

答案 3 :(得分:0)

那是因为您正在使用片段“ this”实例,而不是活动。

替换

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

使用

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