Android Jetpack组件中的作用域状态
在所有应用程序中,始终存在以下三种状态范围: 使用Compose,可通过以下方式实现“每屏幕状态”:Android Jetpack组件中的作用域状态,android,android-viewmodel,android-navigation,android-jetpack-compose,Android,Android Viewmodel,Android Navigation,Android Jetpack Compose,在所有应用程序中,始终存在以下三种状态范围: 使用Compose,可通过以下方式实现“每屏幕状态”: NavHost(navController, startDestination = startRoute) { ... composable(route) { ... val perScreenViewModel = viewModel() // This will be different from } composable(ro
NavHost(navController, startDestination = startRoute) {
...
composable(route) {
...
val perScreenViewModel = viewModel() // This will be different from
}
composable(route) {
...
val perScreenViewModel = viewModel() // this instance
}
...
}
val appStateViewModel = viewModel()
NavHost(navController, startDestination = startRoute) {
...
}
“应用程序状态”可通过以下方式实现:
NavHost(navController, startDestination = startRoute) {
...
composable(route) {
...
val perScreenViewModel = viewModel() // This will be different from
}
composable(route) {
...
val perScreenViewModel = viewModel() // this instance
}
...
}
val appStateViewModel = viewModel()
NavHost(navController, startDestination = startRoute) {
...
}
但是“作用域状态”呢?我们如何在Compose中实现它?这正是我们所使用的
虽然viewModel()
API不允许您直接访问导航图范围的API(没有与navGraphViewModels()API的片段),但您可以编写一个方法来实现这一点:
@Composable
fun <reified VM : ViewModel> NavBackStackEntry.parentViewModel(
navController: NavController
): VM {
// First, get the parent of the current destination
// This always exists since every destination in your graph has a parent
val parentId = destination.parent!!.id
// Now get the NavBackStackEntry associated with the parent
val parentBackStackEntry = navController.getBackStackEntry(parentId)
// And since we can't use viewModel(), we use ViewModelProvider directly
// to get the ViewModel instance, using the lifecycle-viewmodel-ktx extension
return ViewModelProvider(parentBackStackEntry).get()
}
请注意,您不仅限于直接父级:每个父级导航图都可以用于提供更大的范围。如果您需要一个工作解决方案;我目前使用的是compose路由器。有没有办法知道一个可组合的
是否会因为配置更改(如设备旋转)而被处理掉,或者是因为不再需要而被完全处理掉?具体到导航主机
内的行为时,作用域ViewModel的onCleared()
只有当目标(或一组目标,如果您使用的是导航图作用域ViewModel)从后堆栈中弹出并永久销毁时才会被调用。您好@ianhanniballake,我可以问另一个与此问题相关的问题吗。我把它贴在这里: