【问题标题】:Activity view model in Jetpack composeJetpack compose 中的活动视图模型
【发布时间】:2021-08-29 17:53:31
【问题描述】:

在片段中,我们有

private val activityViewModel: MainActivityViewModel by activityViewModels()
private val fragmentViewModel: MainFragmentViewModel by viewModels()

在整个应用程序中获取共享视图模型的实例(活动视图模型)和特定于视图的视图模型(片段视图模型)。

我正在迁移到作曲。

jetpack compose 中如何获取两个不同范围的视图模型?

docs,我可以看到这条线,

viewModel() 返回一个现有的 ViewModel 或在给定范围内创建一个新的。

但是,如何指定视图模型的范围?

附言
我已经浏览过this question,类似但没有任何答案。

【问题讨论】:

    标签: android android-jetpack-compose


    【解决方案1】:

    通常在单个复合树中,例如在setContent 内容中,所有子复合体之间共享一个视图模型范围。

    您可以根据需要覆盖它,使用 LocalViewModelStoreOwner:

    CompositionLocalProvider(
        LocalViewModelStoreOwner provides viewModelStoreOwner
    ) {
        NextComposable()
    }
    

    Compose Navigation 会为每个导航目的地覆盖它。请参阅this answer,了解如何在导航目的地之间共享它。

    【讨论】:

    • 我可以在 Activity 的onCreate 中创建一个 viewModel 的实例并将其传递给每个路由。有什么区别?
    • @JimOvejera viewModel() 将为您创建/缓存视图模型,将其从活动中传递是一种选择,但它需要大量样板代码
    【解决方案2】:

    据此link

    例如,如果我有一个settings 导航图,我可以导航到theme,如果我想theme 使用settingsViewModel,那么该导航图的范围我可以通过以下方式实现:

    private fun NavGraphBuilder.theme(
        navController: NavController,
    ) {
        composable(route = MainSubScreen.Theme.route) {
            val settingsViewModel = hiltViewModel<SettingsViewModel>(
                navController.getBackStackEntry(MainSubScreen.Settings.route)
            )
            Theme(
                settingsViewModel = settingsViewModel,
                backToSettings = { navController.popBackStack() },
            )
        }
    }
    

    或者,如果您希望 theme 使用 settingsViewModel 该范围到 theme 本身。你可以像下面那样做,或者直接在你的 theme 可组合函数中创建一个 settingsViewModel 实例,而无需像这样传递参数。如果你这样做,你会注意到当你从theme 按下回settings 时,settingsViewModel 内的onCleared 将被调用。

    private fun NavGraphBuilder.theme(
        navController: NavController,
    ) {
        composable(route = MainSubScreen.Theme.route) {
            val settingsViewModel = hiltViewModel<SettingsViewModel>()
            Theme(
                settingsViewModel = settingsViewModel,
                backToSettings = { navController.popBackStack() },
            )
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-09-30
      • 1970-01-01
      • 1970-01-01
      • 2023-01-03
      • 2021-10-27
      • 1970-01-01
      • 2021-05-05
      相关资源
      最近更新 更多