android studio
[Android] Navigation 사용법 (Jetpack Compose)
a00896
2025. 2. 28. 22:17
Navigation 원리
- 기본적으로 Navigation은 Stack 기반으로 동작한다.
- 즉, 한 화면에서 다른 화면으로 이동하면, 새로운 화면이 스택에 추가(Push) 되고, 뒤로 가기(Back)를 하면 스택에서 제거(Pop) 된다.
구성요소
- NavController: 네비게이션을 담당하는 컨트롤러.
- NavHost: 화면을 이동할 때 사용되는 컨테이너.
- NavGraph: 화면(경로)과 그 관계를 정의하는 역할.
- Composables: 각각의 화면을 나타내는 함수.
NavGraph
- NavGraph는 앱에서 어떤 화면들이 있고, 그 화면들이 어떻게 연결되는지를 정의하는 구조이다.
- 일반적으로 NavHost 안에서 NavGraph를 설정하게 된다.
Navigation 기본 사용법
- NavController 생성
- NavHost 설정
- 화면(Composable)에서 네비게이션 사용
- 뒤로 가기 기능
1. NavController 생성
- NavController는 화면 이동을 담당하는 객체
- 이를 rememberNavController()를 사용해 생성
val navController = rememberNavController()
2. NavHost 설정
- NavHost를 사용하여 화면과 이동 경로를 정의
NavHost(navController = navController, startDestination = "home") {
composable("home") { HomeScreen(navController) }
composable("profile") { ProfileScreen(navController) }
}
3. 화면(Composable)에서 네비게이션 사용
- 화면에서는 navController.navigate("profile")을 호출하여 다른 화면으로 이동할 수 있다.
@Composable
fun HomeScreen(navController: NavController) {
Column {
Text("Home Screen")
Button(onClick = { navController.navigate("profile") }) {
Text("Go to Profile")
}
}
}
4. 뒤로 가기 기능
- 뒤로 가기는 navController.popBackStack()을 사용
Button(onClick = { navController.popBackStack() }) {
Text("Back")
}
화면 간 데이터 전달
1. String 데이터 전달
- 경로(Route)에서 데이터를 전달할 수 있다.
composable("detail/{itemId}") { backStackEntry ->
val itemId = backStackEntry.arguments?.getString("itemId")
DetailScreen(navController, itemId)
}
이동할 때는 다음과 같이 데이터를 포함하여 이동한다.
navController.navigate("detail/123")
2. 객체 전달 (Seiralizable, parcelable 사용)
val item = MyData("Example", 100)
val json = Uri.encode(Gson().toJson(item)) // JSON 형태로 변환 후 전달
navController.navigate("detail/$json")
composable("detail/{item}") { backStackEntry ->
val json = backStackEntry.arguments?.getString("item") ?: ""
val item = Gson().fromJson(json, MyData::class.java)
DetailScreen(navController, item)
}
Navigation의 백 스택 관리
- Jetpack Compose navigateon은 백 스택을 자동으로 관리한다.
- popUpTo와 launchSingleTop을 활용하면 더 세밀하게 제어할 수 있다.
navController.navigate("home") {
popUpTo("home") { inclusive = true } // 홈 화면을 제외한 모든 스택 제거
launchSingleTop = true // 이미 홈 화면이 있다면 새로 생성하지 않음
}