Android导航组件:如何获取当前导航图的id?

2023-12-19

我使用嵌套导航图来确定范围并在一组片段之间共享我的视图模型。

我还有一个 BaseFragment 类,它获取所需视图模型的引用:

fun provideViewModel() : VM {
        return if(viewModelScopeGraphId != null) {
            ViewModelProvider(findNavController().getViewModelStoreOwner(viewModelScopeGraphId!!)).get(viewModelClass)
        } else {
            ViewModelProvider(this).get(viewModelClass)
        }
     }

我可以覆盖一个属性,viewModelScopeGraphId,如果我需要将视图模型范围限定为具有该特定 id 的导航图(或嵌套导航图)。 理想情况下,我只想设置一个布尔标志,例如useScopedViewModel并获取当前导航图的id,例如:

fun provideViewModel() : VM {
        return if(useScopedViewModel) {
            ViewModelProvider(findNavController().getViewModelStoreOwner(getCurrentNavGraphId())).get(viewModelClass)
        } else {
            ViewModelProvider(this).get(viewModelClass)
        }
     }

我尝试过使用navController.graph.id获取当前图形 id,但我从那里获得的 id 似乎与我的资源 id 不匹配(例如R.id.nav_graph)。我有什么遗漏的吗?


我有一个类似的问题(最后有更多关于我的案例的背景),尝试了一些解决方案,但没有成功。

最后,我放弃了,只是将图 id 作为 Fragment 的参数。

因为它可以帮助您实现自己的解决方案,所以我的解决方案如下所示:

  • 必须创建这个扩展,就像原来的一样navGraphViewModels只接受一个@IdRes navGraphId: Int我想延迟加载参数等(另外我还简化了删除factoryProducer从参数来看,到目前为止我不会将它用于我们的解决方案。
inline fun <reified VM : ViewModel> Fragment.navGraphViewModels(
        noinline graphIdProducer: () -> Int
): Lazy<VM> {
    val backStackEntry by lazy {
        findNavController().getBackStackEntry(graphIdProducer())
    }
    val storeProducer: () -> ViewModelStore = {
        backStackEntry.viewModelStore
    }
    return createViewModelLazy(VM::class, storeProducer, {
        backStackEntry.defaultViewModelProviderFactory
    })
}
  • 在我想使用它的片段中,我使用navArgs,并恢复ViewModel使用上面的扩展:
    private val listenerViewModel: ListenerViewModel by navGraphViewModels {
        navArgs.graphId
    }

    private val navArgs: MyFragmentArgs by navArgs()
  • 以及任何需要“倾听”的人ViewModel,可以简单地使用导航加载navGraphViewModels:
    private val listenerViewModel: ListenerViewModel by navGraphViewModels(
            R.id.my_graph_a
    )    
  • 从另一个图表/片段我简单地做:
    private val listenerViewModel: ListenerViewModel by navGraphViewModels(
            R.id.my_graph_b
    )    

稍微解释一下我的案例的背景:

  • I have two distinct Fragments, where the user can click in a Country selection.
    • 每个片段都位于不同的图表内,因为它们是不同的流。
  • 国家/地区选择是一个片段,其中从 API 加载支持的国家/地区列表,显示它,预先选择任何先前的用户选择(也作为 FragmentArgs 给出),并且用户可以更改选择,这意味着返回到上一个屏幕,使用新选择的值,或者只是返回而不触发任何内容。
  • 我知道并期待发布https://issuetracker.google.com/issues/79672220 https://issuetracker.google.com/issues/79672220,但就今天(2020 年 3 月)而言,它仅适用于alpha.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android导航组件:如何获取当前导航图的id? 的相关文章

随机推荐