Android Fragment 和 Activity 獲取ViewModel 實例
Android 中在 Activity 中創(chuàng)建了一個Fragment 頁面哥艇,并且此時的 Fragment 想用與 Activity 所綁定的ViewModel時,也就是說,F(xiàn)ragment 想監(jiān)聽或者修改 Activity 中 ViewModel 的 livedata, 那么此時就要保證 Fragment 所用的與 Activity 中所用到的是同一個 ViewModel 的實例,才能保證兩個頁面數(shù)據(jù)同時變化。方法一:
首先在 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)
}
}
然后再創(chuàng)建 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 中的第一個參數(shù) ViewModelStoreOwner 對象傳遞的是requireActivity 方法,這個方法里就是獲取當(dāng)前的 Activity 實例 撑帖;如果該位置仍然傳 this 蓉坎,則獲取的是與 Activity 不同的 ViewModel 實例,這樣 Activity 點擊按鈕時 Fragment 頁面的數(shù)值并不會變化胡嘿。
- 方法二 :
通過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。