Cómo obtener el ViewModel de actividad o Fragmento de diferentes ciclos de vida | por Cai Shanglin | Diciembre de 2021
Traducir a través de Google
Cuando usa esto, requireActivity (), requireFragment () … para crear un nuevo ViewModel, en realidad son diferentes, especialmente cuando desea usar el ViewModel de B_Fragment en A_Fragment.
Obtener el modelo de vista de actividad en la actividad
En Actividad, solo puede usar esto para obtener ViewModel, por lo que es relativamente simple, porque
Método de obtención:
val mainViewModel by lazy { ViewModelProvider(this).get(MainViewModel::class.java) }
Hay alrededor de cuatro ViewModels de uso común en Fragment
/代表Fragment自己的生命週期
val viewModel by lazy { ViewModelProvider(this).get(MainViewModel::class.java) }//代表父層Activity的生命週期
val viewModel by lazy { ViewModelProvider(requireActivity()).get(MainViewModel::class.java) }//代表父層Fragment的生命週期
val viewModel by lazy { ViewModelProvider(requireParentFragment()).get(MainViewModel::class.java) }//代表某個Fragment的生命週期
val viewModel by lazy{ViewModelProvider(requireActivity().supportFragmentManager.findFragmentByTag(“TAG”)!!).get(MainViewModel::class.java)}
Si MainViewModel sale a través de esta nueva actividad
val mainViewModel by lazy {ViewModelProvider(this).get(MainViewModel::class.java) }
Establecer diferentes ciclos de vida en Fragment new MainViewModel
Actividad: esto, fragmento: esto
Actividad: Este, fragmento:Necesita actividad ()
Actividad -> Vista de navegación inferior -> Fragmento
Haga clic en el botón en A_Fragment, espero saltar a B_Fragment
Después de hacer clic en un botón en AFragment, salte a BFragment
Actividad
val mainViewModel by lazy { ViewModelProvider(this).get(MainViewModel::class.java) }mainViewModel.jumpLiveData.observe(this, {
when (it) { 0 ->
{//do switch Fragment}
}
}
)
Retazo
val mainViewModel by lazy { ViewModelProvider(requireActivity()).get(MainViewModel::class.java)}mainViewModel.jumpFragment(0)
Segundo○ttomNavigationView-> AFragment-> ViewPager-> IndexFragment
IndexFragment Haga clic para saltar a un IndexFragment
Retazo
val fragmentViewModel by lazy { ViewModelProvider(this).get(AFragmentViewModel::class.java) }class AFragmentViewModel : ViewModel() {private val mSwitchPageLiveData = MutableLiveData() val switchPageLiveData: LiveData= mSwitchPageLiveData fun switchPage(position: Int) {mSwitchPageLiveData.value = position}}private lateinit var viewPager: ViewPager2private lateinit var adapter: FragmentStateAdapteroverride fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)viewPager = view.findViewById(R.id.viewPager)adapter = object : FragmentStateAdapter(this) {override fun getItemCount(): Int = 3override fun createFragment(position: Int): Fragment {return IndexFragment.newInstance(“$position”)}}viewPager.adapter = adapterfragmentViewModel.switchPageLiveData.observe(viewLifecycleOwner,{viewPager.setCurrentItem(it)})}
Fragmento de índice
private val parentFragment by lazy { ViewModelProvider(requireParentFragment()).get(AFragmentViewModel::class.java) }Orprivate val parentFragment by lazy { ViewModelProvider(requireActivity().supportFragmentManager.findFragmentByTag(AFragment.TAG)!!).get(AFragmentViewModel::class.java) }override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)parentFragment.switchPage(position)}
ViewModel solo se puede obtener en Activity o Fragment. La actividad tiene solo un ciclo de vida propio, por lo que es relativamente simple, pero hay varios fragmentos. Cuando quieras declarar un ViewModel de otra clase, debes usar el ciclo de vida correspondiente, de lo contrario liveData no podrá recibir los datos transmitidos. Debido a las diferencias en varias situaciones, solo presentaré los dos con mayor frecuencia.