使用navGraphViewModels访问子NavHostFragment的图范围ViewModel [英] Accessing graph-scoped ViewModel of child NavHostFragment using by navGraphViewModels

查看:1036
本文介绍了使用navGraphViewModels访问子NavHostFragment的图范围ViewModel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Android Jetpack(2.2.0-alpha01)的导航组件.

I am using the Navigation Component of Android Jetpack (2.2.0-alpha01).

我希望使用嵌套在我的主NavHostFragment内的子NavHostFragment,它配备了自己的子导航图.请查看下面的图片作为背景:

I wish to use a child NavHostFragment nested inside my main NavHostFragment, equipped with its own child nav graph. Please view the following image for context:

子导航主机是在MainNavHost堆栈的最前面的片段中这样定义的:

The child nav host is defined like this inside the fragment that is at the front of the MainNavHost's stack:

<fragment
        android:id="@+id/childNavHostFragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="false"
        app:navGraph="@navigation/child_graph" />

在CHILD Nav Host片段前面的片段中,我试图通过使用以下代码来获取范围为R.navigation.child_graph的ViewModel:

Inside the fragment that is at the front of the CHILD Nav Host Fragment, I am trying to get a ViewModel scoped to the R.navigation.child_graph by using the following code:

private val childGraphScopedViewModel: ChildGraphScopedViewModel by navGraphViewModels(R.navigation.child_graph) {
    viewModelFactory
}

访问childGraphScopedViewModel时,出现错误消息,并导致崩溃:

When accessing the childGraphScopedViewModel, I am getting a crash with the error message:

java.lang.IllegalArgumentException: No NavGraph with ID 2131689472 is on the NavController's back stack.

我相信懒惰的init调用by navGraphViewModel()在mainGraph内查找navgraph.

I believe the lazy init call by navGraphViewModel() is looking for the navgraph inside the mainGraph.

如何访问子navHostFragment范围内的ViewModel?谢谢您的时间.

How can I access a child navHostFragment scoped ViewModel? Thank you for your time.

推荐答案

您可以通过提供子NavController

override fun onViewCreated(
     view: View, 
     savedInstanceState: Bundle?
) {
    super.onViewCreated(view, savedInstanceState)

    val childHostFragment = childFragmentManager
          .findFragmentById(R.id.childNavHostFragment) as NavHostFragment

    val childNavController = childHostFragment.navController

    val childViewModel: ChildGraphScopedViewModel = ViewModelProvider(
         childNavController.getViewModelStoreOwner(R.navigation.child_graph)
    ).get(ChildGraphScopedViewModel::class.java)
}

我写了一篇Kotlin扩展程序,以简化操作

I wrote a Kotlin Extension for making it easier

inline fun <reified T: ViewModel> NavController.viewModel(@NavigationRes navGraphId: Int): T {
    val storeOwner = getViewModelStoreOwner(navGraphId)
    return ViewModelProvider(storeOwner)[T::class.java]
}

用法

val viewModel = findNavController().viewModel(R.navigation.nav)

这篇关于使用navGraphViewModels访问子NavHostFragment的图范围ViewModel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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