如何通过 hilt 在 compose ViewModel 中使用 NavController

Mor*_*itz 9 android-jetpack-navigation android-jetpack-compose dagger-hilt

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

现在的问题是:我怎样才能将其注入到刀柄NavController中?ViewModel

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

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

}
Run Code Online (Sandbox Code Playgroud)

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

小智 0

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

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

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

但我认为这不是一个好的做法

  • 为什么不呢?这样,视图模型就具有与按钮单击相关的所有逻辑,并控制导航,因为它们具有状态并且可以控制从其他屏幕传递/接收的内容。这样,视图仅与 ui 相关,并且没有导航逻辑。你怎么认为? (4认同)