我正在尝试导航,比如说从入门到仪表板及其他,并在用户点击仪表板后弹出入门,但仍然通过“后退操作”,我最终再次入门。
这是示例代码:
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MainUI()
}
}
}
@Composable
fun MainUI() {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = "onboarding"
) {
composable("onboarding") {
Column {
Text("I am on onboarding")
Button(onClick = {
navController.navigate("dashboard") {
popUpTo("dashboard") // I want to get rid of onboarding here
}
}) {
Text("go to dashboard")
}
}
}
composable("dashboard") {
Column {
Text("I am on dashboard")
Button(onClick = {
navController.navigate("detail")
}) {
Text("go to detail")
}
}
}
composable("detail") {
Text("I am on detail")
}
}
}
这也行不通
navController.navigate("dashboard") {
popUpTo("dashboard") {
inclusive = true // no difference
}
// ....
popUpTo("onboarding") // also nothing
// ....
popUpTo("onboarding") {
inclusive = true // this crashes -> NavGraph cannot be cast to ComposeNavigator$Destination
}
}
由于某种原因,这种方法有效,因此仪表板被取消,从细节来看,我最终进入了入门阶段 🤦
navController.navigate("detail") {
popUpTo("dashboard") {
inclusive = true
}
}
我发现我的解决方案非常简单,如果我错了,请赐教。
navController.popBackStack()
您可以使用 BackHandler 链接:
@Composable
fun TestScreen() {
BackHandler {
// code
// example - activity.finish()
}
}
正如@James Christian Kaguo 所说,
navController.popBackStack()
是一种选择。但使用此方法时必须小心。由于某种原因,BackQueue 的大小至少为 2,如果弹出的 Backstack 低于该值,导航似乎不再起作用。
因此我编写了以下简单的扩展函数:
fun NavController.navigateBack() {
if (backQueue.size > 2) {
popBackStack()
}
}
好吧,我自己找到了可行的解决方案,但仍然不确定是否需要这个“样板代码”:( 但这按预期工作,意味着一旦从“页面”导航,就会将其关闭。
NavHost(
navController = navController,
startDestination = "onboarding"
) {
navigation(
startDestination = "onboardingUI",
route = "onboarding"
) {
composable("onboardingUI") {
Column {
Text("I am on onboarding")
Button(onClick = {
navController.navigate("dashboard"){
popUpTo("onboarding")
}
}) {
Text("go to dashboard")
}
}
}
}
navigation(startDestination = "dashboardUI", route = "dashboard") {
composable("dashboardUI") {
Column {
Text("I am on dashboard")
Button(onClick = {
navController.navigate("detail"){
popUpTo("dashboard")
}
}) {
Text("go to detail")
}
}
}
}
navigation(startDestination = "detailUI", route = "detail") {
composable("detailUI") {
Text("I am on detail")
}
}
}
}
注意:route 和 startDestination 可组合项的 AKA 名称不能相同
这个问题花了我一段时间才终于弄清楚,因为它有点违反直觉。
假设您有一个
CreateItemScreen
,您不想将其添加到堆栈中,这样当人们点击后退按钮时,他们就无法导航回到它。
您会认为需要使用
navController.navigate("createItem")
修复某些问题,但这是错误的。
您实际上需要做的是转到您的
CreateItemScreen.kt
文件,并找到该文件中的所有navigate
。
例如,如果在创建一个项目后,您导航到其详细信息,that 就是您执行
popUpTo
: 的位置
navController.navigate("itemDetails=$insertedItemId") {
popUpTo("mainScreen")
}
看起来很奇怪,因为它看起来与你的
createItem
路线无关。但它告诉导航堆栈跳过 createItem
路线,转到您希望它弹回的任何其他位置。