탐색 구성요소는 탐색 그래프를 사용하여 앱의 탐색을 관리합니다. 탐색 그래프는 앱 내의 각 대상과 대상 간의 연결을 포함하는 데이터 구조입니다.
대상 유형
일반적으로 대상에는 호스팅된 대상, 대화상자 대상, 활동 대상이라는 세 가지 유형이 있습니다. 다음 표에는 이러한 세 가지 대상 유형과 그 목적이 요약되어 있습니다.
유형 |
설명 |
사용 사례 |
---|---|---|
호스팅된 대상 |
전체 탐색 호스트를 채웁니다. 즉, 호스팅된 대상의 크기가 탐색 호스트의 크기와 동일하며 이전 대상은 표시되지 않습니다. |
기본 및 세부정보 화면 |
대화상자 대상 |
오버레이 UI 구성요소를 표시합니다. 이 UI는 탐색 호스트의 위치 또는 크기와 연결되지 않습니다. 이전 대상은 대상 아래에 표시됩니다. |
알림, 선택, 양식 |
활동 대상 |
앱 내의 고유 화면 또는 기능을 나타냅니다. |
탐색 구성요소와 별도로 관리되는 새 Android 활동을 시작하는 탐색 그래프의 종료 지점 역할을 합니다. 최신 Android 개발에서 앱은 단일 활동으로 구성됩니다. 따라서 활동 대상은 서드 파티 활동과 상호작용할 때 또는 이전 프로세스의 일부로 사용하는 것이 가장 좋습니다. |
이 문서에는 가장 일반적이고 기본적인 대상인 호스팅된 대상의 예가 포함되어 있습니다. 다른 대상에 관한 자세한 내용은 다음 가이드를 참고하세요.
프레임워크
모든 경우에 동일한 일반 워크플로가 적용되지만 탐색 호스트와 그래프를 만드는 정확한 방법은 사용하는 UI 프레임워크에 따라 다릅니다.
- Compose:
NavHost
컴포저블을 사용합니다. Kotlin DSL을 사용하여NavGraph
를 추가합니다. 다음 두 가지 방법으로 그래프를 만들 수 있습니다.- NavHost의 일부로:
NavHost
를 추가하는 과정에서 탐색 그래프를 직접 구성합니다. - 프로그래매틱 방식:
NavController.createGraph()
메서드를 사용하여NavGraph
를 만들고 이를NavHost
에 직접 전달합니다.
- NavHost의 일부로:
- 프래그먼트: 뷰 UI 프레임워크와 함께 프래그먼트를 사용할 때
NavHostFragment
를 호스트로 사용합니다. 탐색 그래프를 만드는 방법에는 여러 가지가 있습니다.- 프로그래매틱 방식: Kotlin DSL을 사용하여
NavGraph
를 만들고 이를NavHostFragment
에 직접 적용합니다.- 프래그먼트와 Compose에 모두 Kotlin DSL과 함께 사용되는
createGraph()
함수는 동일합니다.
- 프래그먼트와 Compose에 모두 Kotlin DSL과 함께 사용되는
- XML: 탐색 호스트와 그래프를 XML로 직접 작성합니다.
- Android 스튜디오 편집기: Android 스튜디오의 GUI 편집기를 사용하여 그래프를 XML 리소스 파일로 만들고 조정합니다.
- 프로그래매틱 방식: Kotlin DSL을 사용하여
Compose
Compose에서 직렬화 가능한 객체 또는 클래스를 사용하여 경로를 정의합니다. 경로는 목적지에 도착하는 방법을 설명하며 목적지에 필요한 모든 정보를 포함합니다.
@Serializable
주석을 사용하여 경로 유형에 필요한 직렬화 및 역직렬화 메서드를 자동으로 만듭니다. 이 주석은 Kotlin 직렬화 플러그인에서 제공합니다. 이 안내에 따라 이 플러그인을 추가합니다.
경로를 정의한 후 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.
}
- 직렬화 가능한 객체는 두 경로인
Profile
및FriendsList
를 각각 나타냅니다. NavHost
컴포저블 호출은NavController
및 시작 대상의 경로를 전달합니다.NavHost
에 전달된 람다는 궁극적으로NavController.createGraph()
를 호출하고NavGraph
를 반환합니다.- 각 경로는 결과
NavGraph
에 목적지를 추가하는NavGraphBuilder.composable<T>()
에 유형 인수로 제공됩니다. composable
에 전달된 람다는NavHost
가 해당 대상에 표시하는 내용입니다.
람다 이해
NavGraph
를 만드는 람다를 더 잘 이해하려면, 또한 이를 고려하여 이전 스니펫과 동일한 그래프를 빌드하려면 NavController.createGraph()
를 사용하여 별도로 NavGraph
를 만들고 NavHost
에 이를 직접 전달하면 됩니다.
val navGraph by remember(navController) {
navController.createGraph(startDestination = Profile)) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
}
}
NavHost(navController, navGraph)
인수 전달
대상에 데이터를 전달해야 하는 경우 매개변수가 있는 클래스로 경로를 정의합니다. 예를 들어 Profile
경로는 name
매개변수가 있는 데이터 클래스입니다.
@Serializable
data class Profile(val name: String)
해당 대상에 인수를 전달해야 할 때마다 라우트 클래스의 인스턴스를 만들어 인수를 클래스 생성자에 전달합니다.
선택적 인수의 경우 기본값이 있는 null 허용 필드를 만듭니다.
@Serializable
data class Profile(val nickname: String? = null)
경로 인스턴스 가져오기
NavBackStackEntry.toRoute()
또는 SavedStateHandle.toRoute()
로 경로 인스턴스를 가져올 수 있습니다. composable()
를 사용하여 대상을 만들 때 NavBackStackEntry
를 매개변수로 사용할 수 있습니다.
@Serializable
data class Profile(val name: String)
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Profile(name="John Smith")) {
composable<Profile> { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(name = profile.name) }
}
이 스니펫에서 다음 사항에 유의하세요.
Profile
경로는"John Smith"
를name
의 인수로 사용하여 탐색 그래프의 시작 대상을 지정합니다.- 대상 자체가
composable<Profile>{}
블록입니다. ProfileScreen
컴포저블은 자체name
인수에profile.name
값을 사용합니다.- 따라서 값
"John Smith"
는ProfileScreen
로 전달됩니다.
간단한 예시
다음은 NavController
와 NavHost
가 함께 작동하는 전체 예시입니다.
@Serializable
data class Profile(val name: String)
@Serializable
object FriendsList
// Define the ProfileScreen composable.
@Composable
fun ProfileScreen(
profile: Profile
onNavigateToFriendsList: () -> Unit,
) {
Text("Profile for ${profile.name}")
Button(onClick = { onNavigateToFriendsList() }) {
Text("Go to Friends List")
}
}
// Define the FriendsListScreen composable.
@Composable
fun FriendsListScreen(onNavigateToProfile: () -> Unit) {
Text("Friends List")
Button(onClick = { onNavigateToProfile() }) {
Text("Go to Profile")
}
}
// Define the MyApp composable, including the `NavController` and `NavHost`.
@Composable
fun MyApp() {
val navController = rememberNavController()
NavHost(navController, startDestination = Profile(name = "John Smith")) {
composable<Profile> { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(
profile = profile,
onNavigateToFriendsList = {
navController.navigate(route = FriendsList)
}
)
}
composable<FriendsList> {
FriendsListScreen(
onNavigateToProfile = {
navController.navigate(
route = Profile(name = "Aisha Devi")
)
}
)
}
}
}
스니펫에서 알 수 있듯이 NavController
를 컴포저블에 전달하는 대신 이벤트를 NavHost
에 노출합니다. 즉, 컴포저블에는 NavController.navigate()
를 호출하는 람다를 NavHost
가 전달하는 () -> Unit
유형의 매개변수가 있어야 합니다.
프래그먼트
이전 섹션에서 설명한 대로 프래그먼트를 사용할 때 Kotlin DSL, XML 또는 Android 스튜디오 편집기를 사용하여 프로그래매틱 방식으로 탐색 그래프를 만들 수 있습니다.
다음 섹션에서는 이러한 다양한 접근 방식을 자세히 설명합니다.
프로그래매틱 방식
Kotlin DSL은 프래그먼트를 사용하여 프로그래매틱 방식으로 탐색 그래프를 만드는 방법을 제공합니다. 이는 XML 리소스 파일을 사용하는 것보다 여러 면에서 더 깔끔하고 현대적인 방법입니다.
두 화면 탐색 그래프를 구현하는 다음 예시를 생각해 보세요.
먼저 app:navGraph
요소를 포함해서는 안 되는 NavHostFragment
를 만들어야 합니다.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
그런 다음 NavHostFragment
의 id
를 NavController.findNavController
에 전달합니다. 이렇게 하면 NavController가 NavHostFragment
와 연결됩니다.
이후에 NavController.createGraph()
를 호출하면 그래프가 NavController
에 연결되고 따라서 NavHostFragment
에도 연결됩니다.
@Serializable
data class Profile(val name: String)
@Serializable
object FriendsList
// Retrieve the NavController.
val navController = findNavController(R.id.nav_host_fragment)
// Add the graph to the NavController with `createGraph()`.
navController.graph = navController.createGraph(
startDestination = Profile(name = "John Smith")
) {
// Associate each destination with one of the route constants.
fragment<ProfileFragment, Profile> {
label = "Profile"
}
fragment<FriendsListFragment, FriendsList>() {
label = "Friends List"
}
// Add other fragment destinations similarly.
}
이러한 방식으로 DSL을 사용하는 것은 Compose에 관한 이전 섹션에서 설명한 워크플로와 매우 유사합니다. 예를 들어 NavController.createGraph()
함수는 두 경우에 모두 NavGraph
를 생성합니다. 마찬가지로 NavGraphBuilder.composable()
은 그래프에 컴포저블 대상을 추가하고 여기서는 NavGraphBuilder.fragment()
가 프래그먼트 대상을 추가합니다.
Kotlin DSL을 사용하는 방법에 관한 자세한 내용은 NavGraphBuilder DSL로 그래프 빌드를 참고하세요.
XML
XML을 직접 작성할 수 있습니다. 다음 예시는 이전 섹션의 두 화면 예시를 반영하며 해당 예시와 같습니다.
먼저 NavHostFragment
를 만듭니다. 이는 실제 탐색 그래프가 포함된 탐색 호스트 역할을 합니다.
NavHostFragment
의 최소 구현은 다음과 같습니다.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navGraph="@navigation/nav_graph" />
</FrameLayout>
NavHostFragment
에는 app:navGraph
속성이 포함되어 있습니다. 이 속성을 사용하여 탐색 그래프를 탐색 호스트에 연결합니다. 다음은 그래프를 구현할 수 있는 방법을 보여주는 예시입니다.
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_graph"
app:startDestination="@id/profile">
<fragment
android:id="@+id/profile"
android:name="com.example.ProfileFragment"
android:label="Profile">
<!-- Action to navigate from Profile to Friends List. -->
<action
android:id="@+id/action_profile_to_friendslist"
app:destination="@id/friendslist" />
</fragment>
<fragment
android:id="@+id/friendslist"
android:name="com.example.FriendsListFragment"
android:label="Friends List" />
<!-- Add other fragment destinations similarly. -->
</navigation>
작업을 사용하여 다양한 대상 간의 연결을 정의합니다. 이 예시에서 profile
프래그먼트에는 friendslist
로 이동하는 작업이 포함되어 있습니다. 자세한 내용은 탐색 작업 및 프래그먼트 사용을 참고하세요.
편집기
Android 스튜디오의 Navigation Editor를 사용하여 앱의 탐색 그래프를 관리할 수 있습니다. 이는 이전 섹션에서 본 것처럼 기본적으로 NavigationFragment
XML을 만들고 수정하는 데 사용할 수 있는 GUI입니다.
자세한 내용은 탐색 편집기를 참고하세요.
중첩 그래프
중첩 그래프를 사용할 수도 있습니다. 여기에는 그래프를 탐색 대상으로 사용하는 작업이 포함됩니다. 자세한 내용은 중첩 그래프를 참고하세요.
추가 자료
핵심 탐색 개념에 관한 자세한 내용은 다음 가이드를 참고하세요.
- 개요: 탐색 구성요소에 관한 일반적인 개요를 읽어 보세요.
- 활동 대상: 사용자를 활동으로 안내하는 대상을 구현하는 방법의 예시입니다.
- 대화상자 대상: 사용자를 대화상자로 안내하는 대상을 만드는 방법의 예시입니다.
- 대상으로 이동: 한 대상에서 다른 대상으로 이동하는 방법을 설명하는 자세한 가이드입니다.
- 중첩 그래프: 하나의 탐색 그래프를 다른 그래프 내에 중첩하는 방법에 관한 자세한 가이드입니다.