設計導覽圖

導覽元件使用「導覽圖」 管理應用程式的導覽。導覽圖是一項資源檔案,其中包含應用程式的所有到達網頁與邏輯連線,或稱為「動作」,使用者可透過執行這種動作,前往不同的到達網頁。您可以使用 Android Studio 中的「Navigation Editor」(導覽編輯器) 管理應用程式的導覽圖。

本主題包含設計應用程式導覽圖的最佳做法和建議。

頂級導覽圖

應用程式的「頂級」 導覽圖應是從啟動應用程式時使用者看到的初始目的地開始,且應包含他們在應用程式中到處瀏覽時所看到的目的地。

圖 1: 頂級導覽圖。

巢狀結構圖

應用程式內的登入流程、精靈或其他子流程通常是 巢狀導覽圖 的最佳呈現方式。透過這種方式,以自主式的子導覽流程建立巢狀結構,使您的應用程式 UI 主要流程更容易理解與管理。此外,巢狀結構圖還可以重複使用。巢狀結構圖也提供一定程度的封裝,也就是說,巢狀結構圖以外的目的地無法直接存取巢狀結構圖內的任何目的地。反而,這些目的地應 navigate() 至巢狀結構圖本身,在這個巢狀結構圖中,內部邏輯可以變更,而不影響這個圖的其餘部分。

以圖 1 的頂級導覽圖為例,假設您只想要求使用者在首次啟動應用程式時查看「title_screen」和「Register」(註冊) 畫面。之後,系統會儲存使用者資訊,並且在應用程式的後續版本中,直接將其導向「match」(相符) 畫面。最佳做法應該是將「match」(相符) 畫面設定為頂級導覽圖的「起始目的地」,然後將標題和註冊畫面移至巢狀結構圖,如圖 2 所示:

圖 2: 頂級導覽圖現在包含巢狀結構圖。

當「match」(相符) 畫面啟動後,您可以查看是否有註冊的使用者。如果使用者尚未註冊,可將其導向註冊畫面。如要進一步瞭解條件式導覽情境,請參閱 條件式導覽

將圖的結構模組化的另一種方法則是,透過父項導覽圖中的 <include> 元素,將一張圖「包含」 在另一張圖中。如此一來,即可完全在單獨模式中或專案中一起定義包含的圖,以達到最大的可重複使用性。

導覽整個程式庫模組

如果您的應用程式仰賴包含導覽圖的 程式庫模組,您可以使用 <include> 元素參照這些導覽圖。

詳情請參閱 多模組專案的導覽最佳做法 一節。

全域動作

應用程式中任何一個可透過多個路徑到達的目的地,都應該定義一個可導覽至該目的地的對應 全域動作。全域動作可用於從任何位置導覽至目的地。

讓我們將這個全域動作套用至程式庫模組範例,其中的勝利目的地和遊戲結束目的地定義了相同的動作。您應將這些通用的全域動作擷取為單一全域動作,並從這兩個目參照對應操作,如以下範例所示:

<?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>

如要進一步瞭解詳情及查看如何在片段中使用全域動作的範例,請參閱導覽說明文件中的 全域動作