这就是我想要做的。
ArrayList
的对象FragmentActivity
中的观察者那里获取该数组
容器(托管所有片段的活动)所以,我要做的是以下事情。
首先,我在其中设置SharedViewModel
并从中获取数据:
class SharedViewModel: ViewModel() {
var personArrayObj:MutableLiveData<ArrayList<Person>> = MutableLiveData()
fun setPersonArray(personArray:ArrayList<Person>){
personArrayObj.value = personArray
}
val getPersonArray:LiveData<ArrayList<Person>>
get() = personArrayObj
}
现在,我在托管所有片段创建的ViewModel
中实例化此MainActivity
,因此,无论片段集位于何处,我都可以从ArrayData
中获取它:
class MainActivity: FragmentActivity(){
private lateinit var viewModel:SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)
viewModel.getPersonArray.observe(this, Observer { it:ArrayList<Person>
Log.d("Array:",""+it)
})
}
}
然后,我要做的最后一件事是从我想要的任何片段中设置该Array的值,然后,如果该值已更改,则将触发主机Activity,因此,要做到这一点,我简单地做一个{ {1}}在我想要的片段上。
当我尝试实例化任何片段中的viewModel.setValue(personArray)
时,我会遇到此问题:
我试图断言!对于null,也可以使用let,但不能使用,我想知道SharedViewModel
的来源是什么
如果我使用FragmentActivity
而不是viewLifecycleOwner
,它对我说,不能使用 Fragment 或 FragmentActivity 来调用它?
有任何线索吗?
谢谢。
答案 0 :(得分:2)
片段提供了一种辅助方法来检索非null活动-requireActivity()
。使用它代替activity
:
viewModel = ViewModelProviders.of(requireActivity()).get(SharedViewModel::class.java)
作为替代方案,您可以在应用程序中包含fragment-ktx
依赖项,并使用by activityViewModels() Kotlin属性扩展而不是完全使用ViewModelProviders.of()
:
val viewModel: SharedViewModel by activityViewModels()
答案 1 :(得分:1)
ViewModelProviders.of() 已弃用。因此,我们可以像下面那样初始化视图模型。
viewModel = ViewModelProvider(requireActivity()).get(SampleViewModel::class.java)
答案 2 :(得分:0)
基本上,问题在于片段类内部的活动上下文将为空,并且ViewModelPorviders
需要非空上下文与之合作。
一种解决方案是使您的ViewModel
对象可空 (因为您的活动可为空)在片段内,如下所示:
var viewModel: SharedViewModel? = null
然后在初始化期间
viewModel = activity?.let { ViewModelProviders.of(it).get(SharedViewModel::class.java) }
答案 3 :(得分:0)
好吧,我没看到
我在我的 Fragment 中创建了viewModel
的一个实例,而在我的 MainActivity 中创建了一个实例,因此,这样做可以防止观察者工作。
为解决这个问题,我只做了一个简单的方法即可返回我在MainActivity
内创建的实例
fun getViewModelInstance():SharedViewModel = viewModel
然后我只需从任何Fragment调用该实例即可使用它
(activity as MainActivity).getViewModelInstance().setPersonArray(personArray)
答案 4 :(得分:0)
将东西放在onActivityCreated()中,而不是onCreateView()中。 这将解决getActivity()可为空的问题... 因为根据片段的生命周期,onActivityCreated()在onCreareView()之后。 活动是在onActivityCreated()的调用上创建的... 因此,getActivity()将返回刚刚创建的活动