Navigation中的Fragments如何与包含此Navigation的Fragment使用同一个ViewModel?

来源:2-11 Jetpack Navigation架构概述

逐梦稚者

2024-03-13

工作中遇到这样的场景:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/content_color"
    android:fitsSystemWindows="true"
    android:layoutDirection="ltr"
    android:orientation="vertical">

	<Layout 
	    android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/container_layout"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_health_options" />

</LinearLayout>

ContainerFragment包含一个FragmentContainerView使用navigation,
navigation中包含3个Fragment。

在3个子Fragment中创建ViewModel时使用

viewModel = ViewModelProvider(requireParentFragment())[HealthOptionsViewModel::class.java]

它们3个能保证获取到同一个ViewModel对象。
ContainerFragment中创建ViewModel时使用

viewModel = ViewModelProvider(this)[HealthOptionsViewModel::class.java]

它拿到的ViewModel对象跟那3个不一样。

打印后发现,Navigation子Fragment的requireParentFragment()得到的是NavHostFragment。

有什么办法让这4个Fragment获取到同一个ViewModel呢?

现在暂时用的方法是传参 requireActivity(),让它们在Activity级别创建同一个对象。但这样有些不合理,只要Activity不退出,这个对象一直不会销毁,在退出Fragment时没办法做一些清理。

写回答

2回答

吃豆人

2024-06-07

我理解的VM中原本就要持有被绑定者的生命周期,以此来决定当前vm的生命周期,希望让三个fragment获取同一个vm,但是又不想让vm跟随当前fragment的生命周期运行,这个本身就不合理。主要是看你的需求,如果仅仅是希望单纯每个fragment持有相同的vm,那就用普通的方式来创建就好。如果想让vm协助实现fragment之间的通信,那就让vm绑定requireAct。

0
0

LovelyChubby

2024-03-13

可以使用requireAct呀。想要清理直接调用viewmodel额方法清理即可
0
0

全新版Jetpack进阶提升,系统性落地短视频App

全新版Jetpack进阶提升,系统性落地短视频App

323 学习 · 114 问题

查看课程