代码之家  ›  专栏  ›  技术社区  ›  Patroy

使用Android导航组件在底部导航中的多个片段之间共享视图模型

  •  0
  • Patroy  · 技术社区  · 6 年前

    我有一个应用程序,在那里我使用带有navHost的片段和连接到它的导航图。这个片段,我们称之为主片段,需要下载一些数据,这些数据将由底部导航中的每个选项卡使用。这看起来像是共享ViewModel的完美用法。

    但是,没有明显的方法将其与底部导航一起使用。有一种方法 navGraphViewModels() 与kotlin代表一起使用:

    val parentViewModel: CourtDetailRootVM by navGraphViewModels(R.id.court_detail)
    

    但这会产生异常:

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

    因为根据文档,这种方法正在寻找当前回溯上的viewModel,而底部导航则不是这样!

    还有其他一些获取父级viewModel的方法,但所有这些方法都需要重用viewModel Factory。我不能使用它,因为我的工厂有带有一些参数的构造函数,需要传递这些参数,而且我无法访问子片段上的这些参数。

    所以,我陷入了困境,看不到这个相当琐碎的问题的任何可能的解决方案

    0 回复  |  直到 6 年前
        1
  •  1
  •   hushed_voice    6 年前

    我两次遇到同样的问题。

    1. 第一个问题是,我创建了一个新的导航文件并使用了它。从技术上讲,这应该是可行的,但我也遇到了同样的错误。 因此,我通过选择导航图中需要分组的所有片段来修复它 right-click->move to nested graph->new graph

    这将产生类似这样的结果:

    <navigation 
        android:id="@+id/checkout_graph" 
        app:startDestination="@id/cartFragment">
    
        <fragment android:id="@+id/orderSummaryFragment".../>
        <fragment android:id="@+id/addressFragment" .../>
        <fragment android:id="@+id/paymentFragment" .../>
        <fragment android:id="@+id/cartFragment" .../>
    
    </navigation>
    

    现在,在初始化ViewModel时,在片段内部执行以下操作

    val viewModel: CheckoutViewModel by navGraphViewModels(R.id.checkout_graph)
    

    如果需要传递viewmodel工厂(可能用于注入viewmodel),可以这样做:

    val viewModel: CheckoutViewModel by navGraphViewModels(R.id.checkout_graph) { viewModelFactory }
    
    1. 第二个问题是我在初始化ViewModel时使用的Id错误。因此,请确保您正在使用当前用于初始化ViewModel的navGraph。