Android Fragment 和 Activity 获取ViewModel 实例
Android 中在 Activity 中创建了一个Fragment 页面,并且此时的 Fragment 想用与 Activity 所绑定的ViewModel时,也就是说,Fragment 想监听或者修改 Activity 中 ViewModel 的 livedata, 那么此时就要保证 Fragment 所用的与 Activity 中所用到的是同一个 ViewModel 的实例,才能保证两个页面数据同时变化。方法一:
首先在 Activity 中获取到 MyViewModel 的实例:
class FragmentActivity : AppCompatActivity() {
val model : MyViewModel by lazy{
ViewModelProvider(this,MyViewModel.MyViewModelFactory()).get(MyViewModel::class.java)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_fragment)
}
}
然后再创建 Fragment, 想在Fragment 中获取到与 Activity 中同一个 ViewModel 实例:
class MyFragment : Fragment() {
val model : BlankViewModel by lazy{
ViewModelProvider(requireActivity(),MyViewModel.MyViewModelFactory()).get(MyViewModel::class.java)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.blank_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
}
在获取 ViewModel 实例时,ViewModelProvider 中的第一个参数 ViewModelStoreOwner 对象传递的是requireActivity 方法,这个方法里就是获取当前的 Activity 实例 ;如果该位置仍然传 this ,则获取的是与 Activity 不同的 ViewModel 实例,这样 Activity 点击按钮时 Fragment 页面的数值并不会变化。
- 方法二 :
通过ktx简化:
添加 ktx 依赖,这里要注意版本:
implementation "androidx.fragment:fragment-ktx:1.2.5"
implementation "androidx.activity:activity-ktx:1.0.0-alpha03"
在 Activity 页面中 :
val model by viewModels<MyViewModel>()
在 Fragment 页面中 :
val model by activityViewModels<MyViewModel>()
这样就可以在 Fragment 中获取到与 Actvity 中同一实例的 ViewModel。