【问题标题】:How to use NavController in compose ViewModel via hilt如何通过 hilt 在 compose ViewModel 中使用 NavController
【发布时间】:2021-05-04 10:13:48
【问题描述】:

我正在使用 jetpack compose 和导航撰写库来从一个屏幕导航到下一个屏幕。通常你会有一个ViewModel 来处理用户交互(例如:viewModel.addItem())。为了完成 addItem 命令,我想通过navController.navigate() 显示另一个屏幕。 ViewModel 本身通过 hiltNavGraphViewModel() 注入到 Composable 中。

现在的问题是:我如何通过刀柄将NavController 注入ViewModel

@HiltViewModel
class ScreenViewModel @Inject constructor(
  private val navController: NavController // where does it come from?
) : ViewModel() {

  fun addItem() {
    navController.navigate("add-item-screen")
  }

}

NavController 是通过可组合层次结构中的 rememberNavController() 方法创建的。我也不想将控制器向下传递到可组合层次结构或使用 CompositionLocal。首选方法是让控制器在 ViewModel 中可用。

【问题讨论】:

  • 将回调放在Compose function Screen 上,不要将NavController 带入ViewModel。我从来没有在撰写时看到过。
  • 并使视图模型使用 StateFlow 进行事件。让那个收集在Screen dan 调用回调函数
  • @RofieSagara 感谢您的回答。我试图将 StateFlow 用作事件,但它有几个问题。按下返回时它不同步。当已经在目标路线上时,检查我们不需要再次导航的内容并不容易。 currentDestination.hasDeepLink() 方法不允许创建相应的路由 URI。

标签: android-jetpack-compose android-jetpack-navigation dagger-hilt


【解决方案1】:

如果你想将它注入到viewmodel,你应该使用应用上下文创建导航控制器,将它安装在应用程序(单例)组件中并将其标记为单例:

@Module
@InstallIn(SingletonComponent::class)
object NavigationModule {

    @Provides
    @Singleton
    fun provideNavController(@ApplicationContext context: Context) = NavHostController(context).apply {
        navigatorProvider.addNavigator(ComposeNavigator())
        navigatorProvider.addNavigator(DialogNavigator())
    }
}

但在我看来这不是一个好习惯

【讨论】:

    猜你喜欢
    • 2023-01-08
    • 2023-02-15
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 2022-09-27
    • 2021-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多