Android JetPack的共享ViewModel生命周期 [英] Shared ViewModel lifecycle for Android JetPack

本文介绍了Android JetPack的共享ViewModel生命周期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

文档 https://developer.android.com/topic/libraries/Architecture/viewmodel#sharing 描述了如何在不同的片段之间共享相同的ViewModel.

The documentation https://developer.android.com/topic/libraries/architecture/viewmodel#sharing describes how we can share the same ViewModel across the different Fragments.

我的单个活动应用程序中有一些复杂的页面,其中包含容器和制表符片段.每个此类页面都有自己的ViewModel,应与所有包含的片段共享.

I have some complicated pages in my single Activity app with a container and tabs fragments. Each such page has own ViewModel which should be shared with all contained fragments.

这里的关键技巧是使用Activity而不是Fragment来保存我的ViewModel.

The key trick here is to use Activity instead of Fragment to hold my ViewModel.

问题是我的活动"可以有多个具有自己的模型的页面,并且始终保持特定页面的视图模型是浪费设备资源.

The problem is that my Activity can have multiple pages with own models and holding the view model for particular page all the time is waste of device resources.

当用户离开页面时,是否有任何方法可以控制ViewModel的生命周期以销毁它?

Is there any way to control the life-cycle of ViewModel to destroy it when user leaves the page?

我想使用容器片段代替Activity:

I thought to use the container fragment instead of Activity:

model = ViewModelProviders.of(getPageContainerFragment()).get(SharedViewModel.class);

但是发现这个主意不是很好,因为所有子片段都应该了解父元素,而这可能不是那么好.

But found this idea not so good because all children fragments should know about the parent which could be not so good.

是否有其他方法可以正确处理这种情况?

Is there any alternatives to tackle properly such case?

推荐答案

由于您使用的是Android Jetpack,因此我可以假定您还使用了导航组件.

Since you are using Android Jetpack, I can assume that you also use Navigation Component.

如果您希望ViewModel仅在处于某些片段中时才保持活动状态,则可以为这些片段创建导航图,以便共享的ViewModel仅在您在这些片段之间浏览时才存在,并在离开它们时被销毁

If you want a ViewModel to only stay active when you are in certain fragments, you can create a navigation chart for those fragments, so that the shared ViewModel only lives while you are browsing between those fragments and is destroyed when you leave them.

假设您的应用程序包含这些片段,

Imagine that your app has these fragments,

  • VehicleFragment:在此片段内,您可以使用制表符(SedanFragment,PickupFragment, OffroadFragment等)
  • UserProfileFragment
  • LoginFragment
  • VehicleFragment: inside this fragment you have tabs(SedanFragment, PickupFragment, OffroadFragment, etc.)
  • UserProfileFragment
  • LoginFragment
  • etc.

并且您希望在Fragment Vehicles及其不同选项卡之间浏览时保持ViewModel处于活动状态.

And you want to keep a ViewModel alive while you are browsing between Fragment Vehicles and its different tabs.

好吧,像这样为他们创建一个嵌套的导航图.

Well, create a nested navigation chart for them like this.

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_navigation.xml"
    app:startDestination="@id/MainFragment">

    <fragment
        android:id="@+id/MainFragment"
        android:name="com.fortatic.apps.guesstheword.ui.welcome.MainFragment"
        android:label="MainFragment"
        tools:layout="@layout/fragment_main">
        <action
            android:id="@+id/action_mainFragment_to_vehicleGraph"
            app:destination="@id/vehicleGraph" />
    </fragment>

    <navigation
        android:id="@+id/vehicleGraph"
        app:startDestination="@id/vehicleFragment" >
        <fragment
            android:id="@+id/vehicleFragment"
            android:name="com.fortatic.apps.guesstheword.ui.game.VehicleFragment"
            android:label="VehicleFragment"
            tools:layout="@layout/fragment_vehicle">
            <action
                android:id="@+id/action_fragmentVehicle_to_sedanFragment"
                app:destination="@id/sedanFragment"/>
            <action
                android:id="@+id/action_fragmentVehicle_to_pickupsFragment"
                app:destination="@id/pickupsFragment"/>
            <action
                android:id="@+id/action_fragmentVehicle_to_offroadFragment"
                app:destination="@id/offroadFragment"/>        
        </fragment>
        <fragment
            android:id="@+id/sedanFragment"
            android:name="com.fortatic.apps.guesstheword.ui.score.SedanFragment"
            android:label="SedanFragment"
            tools:layout="@layout/fragment_sedan">
            ...
        </fragment>
        <fragment
            android:id="@+id/pickupsFragment"
            android:name="com.fortatic.apps.guesstheword.ui.score.PickupFragment"
            android:label="PickupFragment"
            tools:layout="@layout/fragment_pickups">
            ...
        </fragment>
        <fragment
            android:id="@+id/offroadFragment"
            android:name="com.fortatic.apps.guesstheword.ui.score.OffroadFragment"
            android:label="OffroadFragment"
            tools:layout="@layout/fragment_offroad">
            ...
        </fragment>
    </navigation>
</navigation>

创建嵌套的导航图后,只需使用以下方法请求ViewModel实例:

Once you have created the nested navigation graph, simply request an instance of ViewModel using:

private val mySharedViewModel: SharedViewModel by navGraphViewModels(R.id.myNestedGraph) {
    //defaultViewModelProviderFactory or the ViewModelProvider.Factory you are using.
}

您可以在此 answer

这篇关于Android JetPack的共享ViewModel生命周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆