如何在compose中记住重组时的状态?

问题描述 投票:0回答:1
@SuppressLint("DiscouragedApi")
@Composable
fun PuzzleScreen(
    navController: NavHostController,
    sharedViewModel: SharedViewModel,
    letter: String,
    puzzleViewModel: PuzzleViewModel = hiltViewModel(),
) {


    val state by puzzleViewModel.viewState.collectAsState()

    /..../
}

问题是,当我从 PuzzleScreen 转到第二个,然后返回到 PuzzleScreen 时。然后系统重新更新 PuzzleScreen 屏幕。我需要确保状态被保存并被记住。怎么办?

如果不困难,请分享解释如何执行此操作的网站或在 GitHub 上使用它

android android-jetpack-compose state
1个回答
0
投票

如果您使用

hiltViewModel()
,则 Hilt 创建的 ViewModel 实例默认作用域为
NavGraphEntry
。这意味着一旦从后台堆栈中删除该目标,ViewModel 就会被清除。重新访问目的地后,将创建一个新实例。

首先,确保正确处理导航。如果您想导航到后续屏幕而不从后退堆栈中清除当前目的地,请使用

navController.navigate(Destination.SecondDestination.route)

然后要返回到后退堆栈上的上一个目的地,请执行

navController.popBackStack()

这样,ViewModel 状态就不会丢失。

作为替代方案,您可以手动传递 ViewModel 的作用域范围的

NavGraphEntry
。如果您传递根 Composable 的
NavGraphEntry
,则 ViewModel 将可用,直到应用程序关闭。这必须发生在您的可组合项之外,例如在您的 NavHost 中。代码如下所示:

composable(Destination.FirstDestination.route) { navBackStackEntry ->
        val parentEntry = remember(navBackStackEntry) {
            navController.getBackStackEntry(Destination.RootDestination.route)
        }
        val puzzleViewModel = hiltViewModel<PuzzleViewModel>(parentEntry)

        PuzzleScreem(
            // ...
            puzzleViewModel = puzzleViewModel
        })
    }

请注意,您当前观察到的行为与重组无关。每个定义的 ViewModel 在重组期间保留其状态。您的问题与重组无关,而是与导航有关。

© www.soinside.com 2019 - 2024. All rights reserved.