6월 3일의 ⁠#Android11: 베타 버전 출시 행사에 참여하세요.

탐색 그래프 디자인

탐색 구성요소탐색 그래프를 사용하여 앱의 탐색을 관리합니다. 탐색 그래프는 로직 연결 또는 사용자가 한 대상에서 이동하여 다른 대상으로 이동하기 위해 실행하는 작업 및 앱의 모든 대상을 포함하는 리소스 파일입니다. Android 스튜디오의 탐색 편집기를 사용하여 앱의 탐색 그래프를 관리할 수 있습니다.

이 주제에는 앱의 탐색 그래프 디자인에 필요한 모범 사례와 권장사항이 포함되어 있습니다.

최상위 수준 탐색 그래프

앱의 최상위 탐색 그래프는 사용자가 앱을 실행할 때 보는 초기 대상으로 시작해야 하며 앱에서 이동할 때 보는 대상을 포함해야 합니다.

그림 1: 최상위 수준의 탐색 그래프

중첩 그래프

일반적으로 앱 내의 로그인 흐름, 마법사 또는 기타 하위 흐름은 중첩 탐색 그래프로 가장 잘 표현됩니다. 이런 방식으로 자체 포함된 하위 탐색 흐름을 중첩하면 앱 UI의 기본 흐름을 더 쉽게 이해하고 관리할 수 있습니다. 또한 중첩 그래프는 재사용할 수 있습니다. 중첩 그래프는 캡슐화 수준도 제공하므로 중첩 그래프 외부의 대상이 중첩 그래프 내의 대상에 직접 액세스할 수 없습니다. 대신 대상은 자체적으로 중첩 그래프를 navigate()하며 그래프의 나머지 부분에 영향을 주지 않고 내부 로직으로 그래프를 변경할 수 있습니다.

한 예로 그림 1의 최상위 탐색 그래프를 사용하여 앱이 처음 시작할 때만 사용자가 title_screen과 register 화면을 본다고 가정해 보겠습니다. 그 후 사용자 정보는 저장되고 이어지는 앱의 시작 절차에서 match 화면으로 바로 이동해야 합니다. 그림 2와 같이 최상위 탐색 그래프의 시작 대상으로 match 화면을 설정하고 title_screen과 register 화면은 중첩 그래프로 이동하는 것이 좋습니다.

그림 2: 이제 최상위 탐색 그래프에 중첩 그래프가 포함됨

매치 화면이 시작되면 등록된 사용자가 있는지 확인할 수 있습니다. 등록되지 않은 사용자를 등록 화면으로 이동할 수 있습니다. 조건부 탐색 시나리오에 관한 자세한 내용은 조건부 탐색을 참조하세요.

그래프 구조를 모듈화하는 또 다른 방법은 상위 탐색 그래프의 <include> 요소를 통해 다른 그래프 내에 한 그래프를 포함하는 것입니다. 이렇게 하면 포함된 그래프는 별도의 모듈 또는 프로젝트에 함께 정의되어 재사용성이 극대화됩니다.

앱이 라이브러리 모듈에 종속되어 있고 모듈 안에 포함된 탐색 그래프가 있다면 <include> 요소를 사용하여 이러한 탐색 그래프를 참조할 수 있습니다.

퀴즈 게임 예를 토대로 아래 예와 같이 앱의 게임 중심 부분을 별도의 라이브러리 모듈로 분리하여 in_game, results_winner 및 game_over 화면을 여러 앱에서 포함하도록 할 수 있습니다.

<!-- App Module Navigation Graph -->
    <navigation xmlns:android="http://schemas.android.com/apk/res/android"
               xmlns:app="http://schemas.android.com/apk/res-auto"
               xmlns:tools="http://schemas.android.com/tools"
               app:startDestination="@id/match">

       <fragment android:id="@+id/match"
               android:name="com.example.android.navigationsample.Match"
               android:label="fragment_match">

           <!-- Launch into In Game Modules Navigation Graph -->
           <action android:id="@+id/action_match_to_in_game_nav_graph"
               app:destination="@id/in_game_nav_graph" />
       </fragment>

       <include app:graph="@navigation/in_game_navigation" />

    </navigation>
    
<!-- Game Module Navigation Graph -->
    <?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:app="http://schemas.android.com/apk/res-auto"
       android:id="@+id/in_game_nav_graph"
       app:startDestination="@id/in_game">

       <fragment
           android:id="@+id/in_game"
           android:name="com.example.android.gamemodule.InGame"
           android:label="Game">
           <action
               android:id="@+id/action_in_game_to_resultsWinner"
               app:destination="@id/results_winner"  />
           <action
               android:id="@+id/action_in_game_to_gameOver"
               app:destination="@id/game_over"  />
       </fragment>

       <fragment
           android:id="@+id/results_winner"
           android:name="com.example.android.gamemodule.ResultsWinner" >

           <!-- Action back to destination which launched into this in_game_nav_graph-->
           <action android:id="@+id/action_pop_out_of_game"
                               app:popUpTo="@id/in_game_nav_graph" />

       </fragment>

       <fragment
           android:id="@+id/game_over"
           android:name="com.example.android.gamemodule.GameOver"
           android:label="fragment_game_over"
           tools:layout="@layout/fragment_game_over" >

          <!-- Action back to destination which launched into this in_game_nav_graph-->
           <action android:id="@+id/action_pop_out_of_game"
                               app:popUpTo="@id/in_game_nav_graph" />

     </fragment>

    </navigation>
    

기본 앱 모듈에 최상위 그래프를 포함하고 참조해야 하는 탐색을 포함하는 모든 모듈에 관한 Gradle 참조가 있어야 합니다.

전역 작업

둘 이상의 경로를 통해 도달할 수 있는 앱의 대상에는 대상으로 이동하도록 정의된 해당하는 전역 작업이 있어야 합니다. 전역 작업은 어디서든 대상으로 이동하는 데 사용될 수 있습니다.

이를 승리와 게임 종료 대상 두 군데 모두에 정의된 동일한 작업을 가진 라이브러리 모듈 샘플에 적용해 보겠습니다. 아래 예와 같이 이러한 공통 작업을 단일 전역 작업으로 추출하고 작업을 두 대상 모두에서 참조해야 합니다.

<?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:app="http://schemas.android.com/apk/res-auto"
       android:id="@+id/in_game_nav_graph"
       app:startDestination="@id/in_game">

       <!-- Action back to destination which launched into this in_game_nav_graph-->
       <action android:id="@+id/action_pop_out_of_game"
                           app:popUpTo="@id/in_game_nav_graph"
                           app:popUpToInclusive="true"  />

       <fragment
           android:id="@+id/in_game"
           android:name="com.example.android.gamemodule.InGame"
           android:label="Game">
           <action
               android:id="@+id/action_in_game_to_resultsWinner"
               app:destination="@id/results_winner"  />
           <action
               android:id="@+id/action_in_game_to_gameOver"
               app:destination="@id/game_over"  />
       </fragment>

       <fragment
           android:id="@+id/results_winner"
           android:name="com.example.android.gamemodule.ResultsWinner" />

       <fragment
           android:id="@+id/game_over"
           android:name="com.example.android.gamemodule.GameOver"
           android:label="fragment_game_over"
           tools:layout="@layout/fragment_game_over" />

    </navigation>
    

자세히 알아보려면 탐색 문서의 전역 작업과 프래그먼트의 전역 작업을 사용하는 방법의 예를 참조하세요.