Android Fragment 和 Activity 获取ViewModel 实例

  • 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()

在 Fragment 页面中 :

val model by activityViewModels()

这样就可以在 Fragment 中获取到与 Actvity 中同一实例的 ViewModel。

你可能感兴趣的:(Android Fragment 和 Activity 获取ViewModel 实例)