탐색 그래프 설계

탐색 구성요소탐색 그래프를 사용하여 앱의 탐색을 관리합니다. 탐색 그래프는 앱 내의 각 대상과 대상 간의 연결을 포함하는 데이터 구조입니다.

도착 페이지 유형

일반적인 대상에는 호스팅된, 대화상자, 활동의 세 가지 유형이 있습니다. 다음 표에는 이러한 세 가지 대상 유형과 목적이 요약되어 있습니다.

유형

설명

사용 사례

호스팅

전체 탐색 호스트를 채웁니다. 즉, 호스팅된 대상의 크기가 탐색 호스트의 크기와 동일하며 이전 대상은 표시되지 않습니다.

기본 및 세부정보 화면

대화상자

오버레이 UI 구성요소를 표시합니다. 이 UI는 탐색 호스트의 위치 또는 크기와 연결되지 않습니다. 이전 대상은 대상 아래에 표시됩니다.

알림, 선택, 양식

활동

앱 내의 고유 화면 또는 기능을 나타냅니다.

탐색 구성요소와 별도로 관리되는 새 Android 활동을 시작하는 탐색 그래프의 이탈 지점 역할을 합니다.

Modern Android Development에서 앱은 단일 활동으로 구성됩니다. 따라서 활동 대상은 서드 파티 활동과 상호작용할 때 또는 이전 프로세스의 일부로 사용하는 것이 가장 좋습니다.

이 문서에는 가장 일반적이고 기본적인 대상인 호스팅된 대상의 예가 포함되어 있습니다. 다른 대상에 대한 자세한 내용은 다음 가이드를 참조하세요.

프레임워크

모든 사례에 동일한 일반 워크플로가 적용되지만 탐색 호스트와 그래프를 만드는 방법은 사용하는 UI 프레임워크에 따라 다릅니다.

  • Compose: NavHost 컴포저블을 사용합니다. Kotlin DSL을 사용하여 NavGraph를 만듭니다. 다음 두 가지 방법으로 그래프를 만들 수 있습니다.
    • NavHost의 일부로: NavHost를 추가하는 과정에서 탐색 그래프를 직접 구성합니다.
    • 프로그래매틱 방식: NavController.createGraph() 메서드를 사용하여 NavGraph를 만들어 NavHost에 직접 전달합니다.
  • 프래그먼트: 뷰 UI 프레임워크와 함께 프래그먼트를 사용할 때는 NavHostFragment를 호스트로 사용합니다. 탐색 그래프를 만드는 방법에는 여러 가지가 있습니다.
    • 프로그래매틱 방식: Kotlin DSL을 사용하여 NavGraph를 만들고 NavHostFragment에 직접 적용합니다.
      • 프래그먼트와 Compose에서 모두 Kotlin DSL과 함께 사용되는 createGraph() 함수는 동일합니다.
    • XML: 탐색 호스트와 그래프를 XML로 직접 작성합니다.
    • Android 스튜디오 편집기: Android 스튜디오의 GUI 편집기를 사용하여 그래프를 XML 리소스 파일로 만들고 조정합니다.

Compose

Compose에서 NavHost 컴포저블을 사용하여 탐색 그래프를 만듭니다. 다음 예를 참고하세요.

val navController = rememberNavController()

NavHost(navController = navController, startDestination = "profile") {
    composable("profile") { Profile( /* ... */ ) }
    composable("friendslist") { FriendsList( /* ... */ ) }
    // Add more destinations similarly.
}
  1. NavHost 컴포저블 호출은 시작 대상에 해당하는 NavControllerroute 문자열을 전달합니다.
  2. NavHost에 전달된 람다는 최종적으로 NavController.creatGraph()를 호출하고 NavGraph를 반환합니다.
  3. NavGraphBuilder.composable()를 호출하면 결과 NavGraph에 대상이 추가됩니다.
  4. 이 경우 대상은 ProfileFriendsList 컴포저블입니다. 경로 문자열 "profile""friendslist"가 두 대상을 식별하는 키가 됩니다.

NavGraph를 만드는 람다를 더 잘 이해하려면 이전 스니펫과 동일한 그래프를 빌드하려면 NavController.createGraph()를 사용하여 NavGraph를 별도로 만들어 NavHost에 직접 전달하면 됩니다.

val navGraph by remember(navController) {
  navController.createGraph(startDestination = "profile") {
    composable("profile") { Profile() }
    composable("friendslist") { FriendsList() }
  }
}
NavHost(navController, navGraph)

간단한 예시

함께 작동하는 NavControllerNavHost의 간단하지만 완전한 예는 다음과 같습니다.

// Define the Profile composable.
@Composable
fun Profile(onNavigateToFriendsList: () -> Unit) {
  Text("Profile")
  Button(onClick = { onNavigateToFriendsList() }) {
    Text("Go to Friends List")
  }
}

// Define the FriendsList composable.
@Composable
fun FriendsList(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") {
    composable("profile") { Profile(onNavigateToFriendsList = { navController.navigate("friendslist") }) }
    composable("friendslist") { FriendsList(onNavigateToProfile = { navController.navigate("profile") }) }
  }
}

스니펫에서 볼 수 있듯이 NavController를 컴포저블에 전달하는 대신 NavHost에 이벤트를 노출합니다. 즉, 컴포저블에는 NavHostNavController.navigate()를 호출하는 람다를 전달하는 () -> 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>

다음으로, NavHostFragmentidNavController.findNavController()에 전달합니다. 이렇게 하면 NavController가 NavHostFragment와 연결됩니다.

이후에 NavController.createGraph()을 호출하면 그래프를 NavController에 연결하고 결과적으로 NavHostFragment에도 연결됩니다.

// 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"
) {
    // 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입니다.

자세한 내용은 탐색 편집기를 참고하세요.

중첩 그래프

중첩 그래프를 사용할 수도 있습니다. 여기에는 그래프를 탐색 대상으로 사용하는 작업이 포함됩니다. 자세한 내용은 중첩 그래프를 참고하세요.

추가 자료

핵심 탐색 개념에 관한 자세한 내용은 다음 가이드를 참고하세요.

  • 개요: 탐색 구성요소의 일반적인 개요를 읽어야 합니다.
  • 활동 대상: 사용자를 활동으로 안내하는 대상을 구현하는 방법의 예입니다.
  • 대화상자 대상: 사용자를 대화상자로 안내하는 대상을 만드는 방법의 예입니다.
  • 대상으로 이동: 한 대상에서 다른 대상으로 이동하는 방법을 설명하는 자세한 가이드입니다.
  • 중첩 그래프: 하나의 탐색 그래프를 다른 그래프 내에 중첩하는 방법에 관한 자세한 가이드입니다.