3

我有我的活动MainActivity.kt

还有一个 ViewModelMainActivityViewModel.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

4 回答 4

2

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)
}

这将帮助您解决问题。

有关更多详细信息,请查看此。

于 2019-08-28T16:44:31.367 回答
1

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

of(Fragment fragment, ViewModelProvider.Factory factory)

创建一个 ViewModelProvider,它在给定片段的范围处于活动状态时保留 ViewModel。

of(FragmentActivity activity, ViewModelProvider.Factory factory)

创建一个 ViewModelProvider,它在给定 Activity 的作用域处于活动状态时保留 ViewModel。

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

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

class MainFragmentOne{

      lateinit var mainActivityViewModel: MainActivityViewModel
      ...

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

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

于 2019-08-28T17:16:23.820 回答
1

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

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)

如果您使用 aFragment来更新它,请使用以下命令:

    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
            }
        }
    })
}

查看此文档以获取有关ViewModels
Good Luck 的更多信息!我希望这有帮助 :)

于 2019-09-01T07:34:22.100 回答
0

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

代替

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

activity?.let { mainActivityViewModel = ViewModelProviders.of(it, viewModelFactory).get(MainActivityViewModel::class.java) }
于 2019-12-07T21:36:28.063 回答