1

导航撰写版2.4.0-alpha06

我有一个导航抽屉使用Scaffold,部分项目是由 ViewModel 动态生成的。

示例项目是

  • 一种
  • C ...
  • 设置

其中 A、B、C、... 都共享同一个Screen被调用Category的 ,只是传递了不同的参数(例如 Category/A、Category/B)。

在我的里面Scaffold

...

val items = viewModel.getDrawerItems()
// This gives something like 
// ["Home", "Category/A", "Category/B", "Category/C", ..., "Settings"] 
// where each String represents "route"

...

val backstackEntry = navController.currentBackStackEntryAsState()
val currentScreen = Screen.fromRoute(
    backstackEntry.value?.destination?.route
)
Log.d("Drawer", "currentScreen: $currentScreen")

items.forEach { item ->
    DrawerItem(
        item = item, 
        isSelected = currentScreen.name == item.route, 
        onItemClick = {
            Log.d("Drawer", "destinationRoute: ${item.route}")
            navController.navigate(item.route)
            scope.launch {
                scaffoldState.drawerState.close()
            }
        }
    )
}

这段代码运行得很好,除了当我访问主屏幕时,我想清除所有 backstack 到 Home 不包括在内。

我试过添加NavOptionsBuilder

...

navController.navigate(item.route) {
    popUpTo(currentScreen.name) {
        inclusive = true
        saveState = true
    }
}
...

但是,这不起作用,因为currentScreen.name会给出类似的东西,Category/{title}并且 popUpTo 只会尝试从后台堆栈中查找完全匹配的内容,因此它不会弹出任何内容。

有没有真正的撰写导航方法来解决这个问题?或者我应该将最后一个“标题”保存在 ViewModel 中的某个地方并使用它?

来自 Google 的本教程具有类似的结构,但它只是堆叠屏幕,因此从屏幕 A -> B -> A 返回并单击返回只会返回 B -> A,这对我来说不是理想的行为。

先感谢您。

4

2 回答 2

1

当您指定时popUpTo,您应该传递您在这种情况下导航到的相同项目:

navController.navigate(item.route) {
    popUpTo(item.route) {
        inclusive = true
    }
}

也不确定在这种情况下是否需要指定saveState,这取决于您:

是否应保存回栈和当前目的地与 ID 之间的所有目的地的状态,以供以后通过或使用相同 ID 的 restoreState 属性NavOptionsBuilder.popUpTo恢复(注意:无论 inclusive 为 true 还是 false,此匹配 ID 为 true)。NavOptionsBuilder.restoreStateNavOptionsBuilder.popUpTo

于 2021-08-24T03:01:33.790 回答
0

受到@Philip Dukhov回答的启发,我能够实现我想要的。

...

navController.navigate(item.route) {
    // keep backstack until user goes to Home
    if (item.route == Screen.Home.name) {
        popUpTo(item.route) {
            inclusive = true
            saveState = true
        }
    } else {
        // only restoreState for non-home screens
        restoreState = true
    }
...

不幸的是,如果我添加launchSingleTop = true,具有不同参数的屏幕由于某种原因不会重新组合,但这可能是另一个话题。

于 2021-08-24T07:32:06.587 回答