개요
이번 프로젝트에 컴포즈를 사용하는데 컴포즈에서는 화면 전환을 할 때, Jetpack Compose Navigation을 사용해야 한다.
1.Compose Navigation 개요
Compose Navigation은 Android 앱에서 화면 전환을 관리하는 네비게이션 기능을 Jetpack Compose 환경에서 구현할 수 있게 해주는 라이브러리이다.
2.Compose를 사용한 탐색
에 정리된 방식대로 Compose를 사용한 탐색에 대해 정리해보자.
NavController 만들기
-> 네비게이션 상태를 관리하는 컨트롤러, 화면 간 이동을 제어한다.
-> 얘를 통해 다른 화면으로 이동하거나 뒤로 이동할 수 있다.
val navController = rememberNavController()
컴포저블 계층 구조에서 높은 위치에 NavController를 만들어야 한다. 참조해야 하는 모든 컴포저블이 이를 실행할 수 있을 만큼 충분히 높아야 한다.
이 경우 화면 외부의 컴포저블을 업데이트하기 위한 단일 정보 소스로 NavController를 사용할 수 있고, 이는 결국 상태 호이스팅 원칙을 따르는 것이다.
NavHost 만들기
Compose에서는 직렬화 가능한 객체 또는 클래스를 사용해 경로를 정의한다.
*직렬화 -> 객체 또는 데이터를 byte-stream 형태로 변환하는 기술
NavHost
-> 네비게이션을 위한 컨테이너 역할을 하며, 화면의 시작 지점을 정의한다.
-> 네비게이션의 상태를 추적하고, 현재 어떤 화면이 활성화되어 있는지를 결정한다.
NavGraph
-> 앱 내에서 이동할 수 있는 화면과 그 경로를 정의한 설계도이다. 즉, 앱 내의 모든 탐색 대상과 연결 방법을 정의하는 데이터 구조이다.
-> 각 경로(route)에 대응하는 화면을 정의하고, 어떤 화면에서 어떤 화면으로 이동할 수 있는지, 데이터를 어떻게 전달할지 등을 설정한다.
-> NavigationGraph는 NavHost 안에서 정의된다!
@Serializable
object Profile
@Serializable
object FriendsList
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Profile) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
// Add more destinations similarly.
}
여기서 NavigationGraph는 composable 블록들로 화면과 경로를 정의한 부분이다.
위의 코드에 대해 자세히 설명해보자면 다음과 같다.
1. 직렬화 가능한 객체는 두 경로 Profile과 FrendList
2. NavHost 컴포저블 호출은 NavController 및 시작 경로 Profile을 전달받는다.
3. NavHost에 전달된 람다는 궁극적으로 NavController.createGraph()를 호출하고 NavGraph를 반환한다.
4. composable<T>는 각 화면을 네비게이션 경로에 매핑하는 함수이다. 여기서 T는 화면 또는 경로와 연결된 데이터 타입을 의미한다!
5. composable에 전달된 람다는 NavHost에서 표시하는 내용이다.
<참고>
Composable
-> 각 화면(Screen)을 구성하는 Composable 함수를 정의하고, 특정 route에 맞게 연결된다.
composable("home") { HomeScreen(navController) }
Routes
-> 각 화면의 경로를 정의하고, 문자열을 사용해 구분한다. 이를 통해 특정 경로로 이동할 수 있다.
navController.navigate("detail")
인수를 통해 이동
Navigation Compose는 구성 가능한 대상 간의 인수 전달도 지원한다. 이렇게 하려면 기본 탐색 라이브러리를 사용할 때, 딥 링크에 인수를 추가하는 방법과 유사한 방법으로 인수 자리표시자를 경로에 추가해줘야 한다.
NavHost(startDestination = "profile/{userId}") {
...
composable("profile/{userId}") {...}
}
이때, 기본적으로 모든 인수는 문자열로 파싱된다.
인수 전달하는 단계
1) 인수를 포함한 경로 정의
-> 경로를 정의할 때, 인수를 경로에 포함시킬 수 있다.
composable("profile/{userId}") { backStackEntry ->
val userId = backStackEntry.arguments?.getString("userId")
ProfileScreen(userId)
}
여기서 {userId}는 userId 라는 인수를 받을 수 있는 경로의 자리 표시자이다.
* backStackEntry
-> 네비게이션 스택의 상태를 나타내고, 현재 표시되는 화면의 상태나 전달된 인수를 접근할 때 사용된다.
-> 얘를 바탕으로 현재 화면이 네비게이션 백스택에 있을 때 어떤 상태인지, 그리고 이전 화면에서 어떤 데이터를 받아왔는지를 알 수 있다.
composable("profile/{userId}") { backStackEntry ->
val userId = backStackEntry.arguments?.getString("userId")
ProfileScreen(userId)
}
또는 받아오는 부분에서 backStackEntry.toRoute()를 통해 가져올 수 있다.
2) 인수를 포함해 네비게이션
-> 특정 경로로 이동 할 때 인수를 경로에 포함하여 전달한다.
navController.navigate("profile/$userId")
'Android > Android Compose' 카테고리의 다른 글
[Android] Compose - (7) CompositionLocal (0) | 2024.11.13 |
---|---|
[Android] Compose - (6) 부수효과 첫 번째 (0) | 2024.11.12 |
[Android] Compose - (4) 컴포저블 수명 주기 (2) | 2024.10.22 |
[Android] Compose - (3) 상태를 호이스팅할 대상 위치 (0) | 2024.08.19 |
[Android] Compose UI - (3) 페이저(Pager) (1) | 2024.08.15 |