Navigation
1. Setup
Phần tiêu đề “1. Setup”Dependencies
Phần tiêu đề “Dependencies”implementation("androidx.navigation:navigation-compose:2.7.7")2. NavController và NavHost
Phần tiêu đề “2. NavController và NavHost”@Composablefun MyApp() { val navController = rememberNavController()
NavHost( navController = navController, startDestination = "home" ) { composable("home") { HomeScreen( onNavigateToDetail = { id -> navController.navigate("detail/$id") } ) } composable("detail/{id}") { backStackEntry -> val id = backStackEntry.arguments?.getString("id") DetailScreen(id = id) } }}3. Navigate với Arguments
Phần tiêu đề “3. Navigate với Arguments”Path Arguments
Phần tiêu đề “Path Arguments”NavHost(...) { composable("detail/{userId}") { backStackEntry -> val userId = backStackEntry.arguments?.getString("userId") DetailScreen(userId) }}
// NavigatenavController.navigate("detail/123")Type-safe Arguments
Phần tiêu đề “Type-safe Arguments”composable( route = "detail/{id}", arguments = listOf( navArgument("id") { type = NavType.IntType } )) { backStackEntry -> val id = backStackEntry.arguments?.getInt("id") ?: 0 DetailScreen(id)}Optional Arguments
Phần tiêu đề “Optional Arguments”composable( route = "search?query={query}", arguments = listOf( navArgument("query") { type = NavType.StringType defaultValue = "" nullable = true } )) { backStackEntry -> val query = backStackEntry.arguments?.getString("query") SearchScreen(query)}
// NavigatenavController.navigate("search?query=kotlin")4. Navigation Back Stack
Phần tiêu đề “4. Navigation Back Stack”// Navigate và pop tất cả đến destinationnavController.navigate("home") { popUpTo("home") { inclusive = true }}
// Navigate và clear back stacknavController.navigate("login") { popUpTo(0) { inclusive = true }}
// Pop backnavController.popBackStack()
// Navigate up (respect parent)navController.navigateUp()5. Bottom Navigation
Phần tiêu đề “5. Bottom Navigation”@Composablefun MainScreen() { val navController = rememberNavController()
Scaffold( bottomBar = { NavigationBar { val navBackStackEntry by navController.currentBackStackEntryAsState() val currentRoute = navBackStackEntry?.destination?.route
listOf( BottomNavItem("home", "Home", Icons.Default.Home), BottomNavItem("search", "Search", Icons.Default.Search), BottomNavItem("profile", "Profile", Icons.Default.Person) ).forEach { item -> NavigationBarItem( icon = { Icon(item.icon, item.label) }, label = { Text(item.label) }, selected = currentRoute == item.route, onClick = { navController.navigate(item.route) { popUpTo(navController.graph.startDestinationId) { saveState = true } launchSingleTop = true restoreState = true } } ) } } } ) { padding -> NavHost( navController, startDestination = "home", modifier = Modifier.padding(padding) ) { composable("home") { HomeScreen() } composable("search") { SearchScreen() } composable("profile") { ProfileScreen() } } }}6. Nested Navigation
Phần tiêu đề “6. Nested Navigation”NavHost(navController, startDestination = "main") { // Main graph navigation(startDestination = "home", route = "main") { composable("home") { HomeScreen() } composable("detail/{id}") { DetailScreen() } }
// Auth graph navigation(startDestination = "login", route = "auth") { composable("login") { LoginScreen() } composable("register") { RegisterScreen() } }}7. Deep Links
Phần tiêu đề “7. Deep Links”composable( route = "detail/{id}", deepLinks = listOf( navDeepLink { uriPattern = "myapp://detail/{id}" }, navDeepLink { uriPattern = "https://myapp.com/detail/{id}" } )) { backStackEntry -> DetailScreen(backStackEntry.arguments?.getString("id"))}8. Passing Data Back
Phần tiêu đề “8. Passing Data Back”// Screen A: Set result listenerval result = navController.currentBackStackEntry ?.savedStateHandle ?.getLiveData<String>("key")
// Screen B: Return resultnavController.previousBackStackEntry ?.savedStateHandle ?.set("key", "result value")navController.popBackStack()9. Animation
Phần tiêu đề “9. Animation”composable( route = "detail", enterTransition = { slideInHorizontally(initialOffsetX = { 1000 }) }, exitTransition = { slideOutHorizontally(targetOffsetX = { -1000 }) }, popEnterTransition = { slideInHorizontally(initialOffsetX = { -1000 }) }, popExitTransition = { slideOutHorizontally(targetOffsetX = { 1000 }) }) { DetailScreen()}10. Type-Safe Navigation (Kotlin Serialization)
Phần tiêu đề “10. Type-Safe Navigation (Kotlin Serialization)”@Serializabledata class Detail(val id: Int)
@Serializableobject Home
NavHost(navController, startDestination = Home) { composable<Home> { HomeScreen() } composable<Detail> { backStackEntry -> val detail: Detail = backStackEntry.toRoute() DetailScreen(detail.id) }}
// NavigatenavController.navigate(Detail(id = 123))📝 Tóm tắt
Phần tiêu đề “📝 Tóm tắt”| Concept | Mô tả |
|---|---|
| NavController | Điều khiển navigation |
| NavHost | Container cho destinations |
| composable | Định nghĩa destination |
| navArgument | Truyền arguments |
| popUpTo | Pop back stack |
| Deep Links | External URLs |
| Nested Navigation | Graphs lồng nhau |