JETPACK组成:使用导航组件更改底部NAV背部按下行为

发布于 2025-02-06 13:11:54 字数 2285 浏览 1 评论 0原文

我终于开始使用Android的作曲,目前被困在导航中。我有两个问题:

1。 我已经实现了一个带有三个按钮的底部导航,其中一个按钮触发了一个嵌套导航图,例如:

 HOME  ---  CONTACTS  ---  FAVOURITES 
   |            
DETAILS 

当我在家中打开详细信息时,行为是正确的,嵌套图中的状态和最后一个目的地是记忆的当我再次在家中点击时,它会保留状态并切换回细节。但是,如果我在其他任何选项卡上,然后向后倾斜,它会使我回到家,但它重置了状态,它并不能使我重新介绍。我该如何实现?

导航栏:

@Composable
fun BottomNavigationBar(navController: NavHostController) {
BottomNavigation {
    val backStackEntry by navController.currentBackStackEntryAsState()
    val currentRoute = backStackEntry?.destination?.route

    BottomNavigationCollection.items.forEach { navItem ->
        BottomNavigationItem(
            selected = currentRoute == navItem.route,
            onClick = {
                navController.navigate(navItem.route) {
                    popUpTo(navController.graph.findStartDestination().id) {
                        saveState = true
                    }
                    launchSingleTop = true
                    restoreState = true
                }
            },
            icon = {
                Icon(
                    imageVector = navItem.icon,
                    contentDescription = navItem.title
                )
            },
            label = {
                Text(text = navItem.title)
            },
        )
    }
}

导航主机:

@Composable
fun NavigationHost(navController: NavHostController) {
NavHost(
    navController = navController,
    startDestination = NavigationRoutes.Home.route,
    route = "root"
) {
    homeGraph(navController)

    composable(NavigationRoutes.Contacts.route) {
        ContactsScreen()
    }

    composable(NavigationRoutes.Favorites.route) {
        FavouritesScreen()
    }
}

}

嵌套家庭导航图:

fun NavGraphBuilder.homeGraph(navController: NavController) {
navigation(
    startDestination = NavigationRoutes.Dashboard.route,
    route = NavigationRoutes.Home.route
) {
    composable(NavigationRoutes.Dashboard.route) {
        DashboardScreen(navController)
    }

    composable(NavigationRoutes.Details.route) {
        DetailsScreen(navController)
    }
}

}

2。 当我回到家中,整个导航堆栈清除并再次向后压时,该应用程序自然会关闭。当时,如何拦截背部按下并实施“再次点击到退出”确认功能?

I finally started using Compose for Android and I am currently stuck at navigation. I have two questions:

1.
I have implemented a bottom navigation with three buttons and one of the buttons triggeres a nested navigation graph, like:

 HOME  ---  CONTACTS  ---  FAVOURITES 
   |            
DETAILS 

So when I open details screen from home and switch tabs, the behavior is correct, the state and last destination in the nested graph is memorized and when I tap again on home, it keeps the state and switches back to details. However, if I am on any of the other tabs and press back, it brings me to home but it resets the state, it doesn't bring me back into details. How can I achieve that?

Navigation Bar:

@Composable
fun BottomNavigationBar(navController: NavHostController) {
BottomNavigation {
    val backStackEntry by navController.currentBackStackEntryAsState()
    val currentRoute = backStackEntry?.destination?.route

    BottomNavigationCollection.items.forEach { navItem ->
        BottomNavigationItem(
            selected = currentRoute == navItem.route,
            onClick = {
                navController.navigate(navItem.route) {
                    popUpTo(navController.graph.findStartDestination().id) {
                        saveState = true
                    }
                    launchSingleTop = true
                    restoreState = true
                }
            },
            icon = {
                Icon(
                    imageVector = navItem.icon,
                    contentDescription = navItem.title
                )
            },
            label = {
                Text(text = navItem.title)
            },
        )
    }
}

Navigation Host:

@Composable
fun NavigationHost(navController: NavHostController) {
NavHost(
    navController = navController,
    startDestination = NavigationRoutes.Home.route,
    route = "root"
) {
    homeGraph(navController)

    composable(NavigationRoutes.Contacts.route) {
        ContactsScreen()
    }

    composable(NavigationRoutes.Favorites.route) {
        FavouritesScreen()
    }
}

}

Nested Home Navigation Graph:

fun NavGraphBuilder.homeGraph(navController: NavController) {
navigation(
    startDestination = NavigationRoutes.Dashboard.route,
    route = NavigationRoutes.Home.route
) {
    composable(NavigationRoutes.Dashboard.route) {
        DashboardScreen(navController)
    }

    composable(NavigationRoutes.Details.route) {
        DetailsScreen(navController)
    }
}

}

2.
When I am back in home with the entire navigation stack clear and press back once more, naturally the app closes. How can I intercept back press and implement a "tap again to exit" confirmation feature at that point?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

滥情稳全场 2025-02-13 13:11:54

我无法回答您的第一个问题,但是对于您的第二个问题:我只是偶然发现了 Backandler 。我只是快速尝试了一下,它被打电话给了而不是关闭应用程序,因此应该解决您的问题。

I cannot answer your first question, but for your second one: I just stumbled upon BackHandler. I just tried it real quick and it got called instead of closing the app, so that should solve your issue.

顾北清歌寒 2025-02-13 13:11:54

我使用空的 Backhandler 。由于您的联系人和收藏夹屏幕本身没有任何嵌套导航,因此在您的情况下这应该有效。 BackHandler将消耗后按下,并阻止将其解释为popbackstack

@Composable
fun Contacts() {
    val context = LocalContext.current
    
    BackHandler {
        // leave empty
    }
}

BackHandler中,您还可以放置“单击两次以关闭应用程序”的行为。您可以这样尝试:

@Composable
fun Contacts() {
    val context = LocalContext.current
    val coroutineScope = rememberCoroutineScope()
    var firstPressed by remember { mutableStateOf(false) }
    
    BackHandler() {
        if (firstPressed) {
            val activity = (context as? Activity)
            activity?.finish()
        } else {
            firstPressed = true
            Toast.makeText(context, "Press back again to exit", Toast.LENGTH_SHORT).show()
            coroutineScope.launch {
                delay(2000L)  // set delay here as wished
                firstPressed = false
            }   
        }
    }
}

I resolved the problem using an empty BackHandler. As your Contacts and Favorites screens do not have any nested navigation themselves, this should work in your case. The BackHandler will consume the back press and will prevent it from being interpreted as popBackStack.

@Composable
fun Contacts() {
    val context = LocalContext.current
    
    BackHandler {
        // leave empty
    }
}

In the BackHandler, you also could place a "click twice to close app" behavior. You can try it like this:

@Composable
fun Contacts() {
    val context = LocalContext.current
    val coroutineScope = rememberCoroutineScope()
    var firstPressed by remember { mutableStateOf(false) }
    
    BackHandler() {
        if (firstPressed) {
            val activity = (context as? Activity)
            activity?.finish()
        } else {
            firstPressed = true
            Toast.makeText(context, "Press back again to exit", Toast.LENGTH_SHORT).show()
            coroutineScope.launch {
                delay(2000L)  // set delay here as wished
                firstPressed = false
            }   
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文