導覽圖可包含以下項目的任意組合:
這種靈活性可讓您結合較小的導覽圖, 構成應用程式的完整導覽圖 圖表由不同的模組提供。
就本主題中的範例而言
聚焦於功能模組
至少一項功能
提供單一導覽圖,用來封裝所有目的地
以便實作這項功能在正式版應用程式中
較低層級的子模組,為這個較高層級的實作詳細資料
功能模組。每項功能模組都會直接或顯示在層級中
間接參與
app
模組。範例
在本文件中使用的多模組應用程式中
以下結構:
每個功能模組都是獨立單元,具有專屬導覽圖
以及目的地app
模組依附各個程式庫模組,因此您必須將程式庫模組做為實作詳細資料新增至其 build.gradle
檔案中,如下所示:
Groovy
dependencies { ... implementation project(":feature:home") implementation project(":feature:favorites") implementation project(":feature:settings")
Kotlin
dependencies { ... implementation(project(":feature:home")) implementation(project(":feature:favorites")) implementation(project(":feature:settings"))
app
模組的功用
app
模組負責為您的
並將 NavHost
新增至 UI。在 app
模組的
您可以藉由使用
<include>
。雖然
<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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/home_nav_graph">
<include app:graph="@navigation/home_navigation" />
<include app:graph="@navigation/favorites_navigation" />
<include app:graph="@navigation/settings_navigation" />
</navigation>
將程式庫納入頂層導覽圖後,您可以視需要瀏覽至程式庫圖表。舉例來說,您可以建立一項動作,以便從導覽圖中的某個片段瀏覽至設定圖表,如下所示:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/home_nav_graph">
<include app:graph="@navigation/home_navigation" />
<include app:graph="@navigation/favorites_navigation" />
<include app:graph="@navigation/settings_navigation" />
<fragment
android:id="@+id/random_fragment"
android:name="com.example.android.RandomFragment"
android:label="@string/fragment_random" >
<!-- Launch into Settings Navigation Graph -->
<action
android:id="@+id/action_random_fragment_to_settings_nav_graph"
app:destination="@id/settings_nav_graph" />
</fragment>
</navigation>
多個功能模組需要參照一組通用時
到達網頁 (例如登入圖表) 請勿納入這些目的地
各項功能模組的導覽圖中常見的目的地。而應改為將這些常用目的地新增至 app
模組的導覽圖中。這樣每個功能模組就能進行跨功能模組導覽
即可導航到這些常用目的地
在上述範例中,動作指定的導覽目的地為 @id/settings_nav_graph
。這個 ID 是指隨附圖表 @navigation/settings_navigation.
中定義的目的地。
應用程式模組中的頂層導覽
導覽元件含有 NavigationUI
類別。這個類別包含多種靜態方法,用於管理頂端應用程式列、導覽匣和底部導覽的導覽行為。如果您應用程式的
頂層目的地是由功能提供的 UI 元素組成
app
模組是自然將頂層放在
導覽和 UI 元素由於應用程式模組取決於
共同協作功能模組,讓所有目的地都能存取
擷取自應用程式模組定義的程式碼這表示如果項目 ID 與目的地 ID 相符,您就可以使用 NavigationUI
將目的地連結至選單項目。
在圖 2 中,範例 app
模組的主要活動中定義了 BottomNavigationView
。選單中的選單項目 ID 與程式庫圖表的導覽圖 ID 相符:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@id/home_nav_graph"
android:icon="@drawable/ic_home"
android:title="Home"
app:showAsAction="ifRoom"/>
<item
android:id="@id/favorites_nav_graph"
android:icon="@drawable/ic_favorite"
android:title="Favorites"
app:showAsAction="ifRoom"/>
<item
android:id="@id/settings_nav_graph"
android:icon="@drawable/ic_settings"
android:title="Settings"
app:showAsAction="ifRoom" />
</menu>
如要讓 NavigationUI
處理底部導覽,請透過主活動類別中的 onCreate()
呼叫 setupWithNavController()
,如以下範例所示:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController findViewById<BottomNavigationView>(R.id.bottom_nav) .setupWithNavController(navController) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); NavHostFragment navHostFragment = (NavHostFragment) supportFragmentManager.findFragmentById(R.id.nav_host_fragment); NavController navController = navHostFragment.getNavController(); BottomNavigationView bottomNav = findViewById(R.id.bottom_nav); NavigationUI.setupWithNavController(bottomNav, navController); }
設定好這個程式碼後,當使用者點選底部導覽項目時,NavigationUI
就會瀏覽至適當的程式庫圖表。
請注意,一般來說,最好讓應用程式模組 必須硬性依賴內嵌在深層內部的特定目的地 您的功能模組導覽圖在大多數情況下,您會希望 模組,瞭解任何內嵌或內含的進入點 導覽圖 (這適用於功能模組以外的情況)。如要連結至程式庫導覽圖深處的目的地,建議您使用深層連結。如要讓程式庫瀏覽至其他程式庫導覽圖中的目的地,深層連結也是唯一的做法。
跨功能模組導覽
在編譯期間,獨立功能模組看不到彼此, 因此無法使用 ID 導覽至其他模組中的目的地。請改為使用深層連結,直接導覽至與隱含深層連結相關聯的目的地。
延續上一個範例,假設您需要從
:feature:home
模組至 :feature:settings
中的巢狀目的地
後續課程我們將逐一介紹
預先訓練的 API、AutoML 和自訂訓練只要在設定中新增連往該到達網頁的深層連結即可
導覽圖,如下所示:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/settings_nav_graph"
app:startDestination="@id/settings_fragment_one">
...
<fragment
android:id="@+id/settings_fragment_two"
android:name="com.example.google.login.SettingsFragmentTwo"
android:label="@string/settings_fragment_two" >
<deepLink
app:uri="android-app://example.google.app/settings_fragment_two" />
</fragment>
</navigation>
接著將下列程式碼新增至首頁中按鈕的 onClickListener
片段:
Kotlin
button.setOnClickListener { val request = NavDeepLinkRequest.Builder .fromUri("android-app://example.google.app/settings_fragment_two".toUri()) .build() findNavController().navigate(request) }
Java
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { NavDeepLinkRequest request = NavDeepLinkRequest.Builder .fromUri(Uri.parse("android-app://example.google.app/settings_fragment_two")) .build(); NavHostFragment.findNavController(this).navigate(request); } });
與使用動作或目的地 ID 進行瀏覽不同,您可以瀏覽至所有圖表中的任何 URI,甚至可以跨模組進行瀏覽。
使用 URI 進行瀏覽時,系統「不會」重設返回堆疊。這項行為與明確深層連結導覽不同。在明確深層連結導覽流程中,返回堆疊會在導覽時遭取代。