Android Fragments Android导航组件的片段重建问题

lstz6jyr  于 12个月前  发布在  Android
关注(0)|答案(1)|浏览(199)

我们的项目是使用jetpact组成和导航组件。
我们有两个片段-片段A和B。在片段A中,UI有点复杂,因为有多个元素,如View Pager和lazycolumn。Lazy column根据viewpager选择进行更新。从Fragmnt A中选择lazy column中的项目时,它将导航到Fragment B。我们目前使用的是android导航组件。问题是导航组件将进行片段替换。这将重新创建Fragment由于这一点,我们失去了片段A的UI状态。我们不能将片段B作为对话框的目的地,因为当片段C从片段B打开时,它应该在堆栈中。
我们找到了3个解决方案,但都有一些问题。
1.在ViewModel中保存UI状态,并在重新创建片段A时恢复状态。
--我们可以在ViewModel中保存Viewpager的UI状态。但是保存列表滚动状态将不起作用,因为列表将在Viewpager状态更新后刷新。这种方法再次执行视图重建,这将在从片段B按回时产生性能延迟
1.在将fragment replace替换为Fragment Add之后,提供CustomFragmentNavigator。
--这将引入更多的样板代码,我们觉得这是一个反模式,因为谷歌有目的地在导航中进行片段替换。
1.在片段A中执行旧的片段事务,而不是使用导航组件。当需要添加片段时,使用混合方法,使用旧的片段事务或使用导航组件。
--由于我们正在使用navhost片段,无法获取容器ID进行正常的片段事务。我们只有根布局的容器片段。
希望能有一些技术上的指导,解决这个根本问题的方法应该是什么。

flvtvl50

flvtvl501#

根据文件:
当您使用popUpTo导航到目标时,您可以选择保存从回退堆栈弹出的所有目标的状态
要启用此选项,请在关联的操作中将popUpToSaveState定义为true,或调用NavController.navigate()
当您导航到目的地时,您也可以将restoreSaveState定义为true,以便在destination属性中自动恢复与目的地关联的状态

XML示例

<action
  android:id="@+id/action_a_to_b"
  app:destination="@id/b"
  app:popUpTo="@+id/a"
  app:popUpToInclusive="true"
  app:restoreState=”true”
  app:popUpToSaveState="true"/>

字符串

编写示例

@Composable
fun MyAppNavHost(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController(),
    startDestination: String = "destination_a"
) {
    NavHost(
        modifier = modifier,
        navController = navController,
        startDestination = startDestination
    ) {
        composable("destination_a") {
            DestinationA(
                onNavigateToB = {
                // Pop everything up to the "destination_a" destination off the back stack before
                // navigating to the "destination_b" destination
                    navController.navigate("destination_b") {
                        popUpTo("destination_a") {
                            inclusive = true
                            saveState = true
                        }
                    }
                },
            )
        }
        composable("destination_b") { DestinationB(/* ... */) }
    }
}

@ Composable
fun DestinationA(onNavigateToB: () -> Unit) {
    Button(onClick = onNavigateToB) {
        Text("Go to A")
    }
}


更精细地说,您可以通过以下方式更改调用NavController.navigate()的方式:

// Pop everything up to the destination_a destination off the back stack before
// navigating to the "destination_b" destination
navController.navigate("destination_b") {
    popUpTo("destination_a")
}

// Pop everything up to and including the "destination_a" destination off
// the back stack before navigating to the "destination_b" destination
navController.navigate("destination_b") {
    popUpTo("destination_a") { inclusive = true }
}

// Navigate to the "search” destination only if we’re not already on
// the "search" destination, avoiding multiple copies on the top of the
// back stack
navController.navigate("search") {
    launchSingleTop = true
}


有关更多信息,请参阅此链接:导航和返回堆栈

相关问题