本頁面提供模組化導覽程式碼的指南。本指南旨在補充應用程式模組化的一般指南。
總覽
模組化導覽程式碼,是指將相關的導覽鍵及其代表的內容,分隔成個別模組。這可明確劃分責任,並讓您在應用程式的不同功能之間瀏覽。
如要將導覽程式碼模組化,請按照下列步驟操作:
- 為應用程式中的每項功能建立兩個子模組:
api和impl - 將各項功能的導覽鍵放入其
api模組 - 將每項功能的
entryProviders和可導覽內容放入相關聯的impl模組 - 直接或使用依附元件插入,將
entryProviders提供給主要應用程式模組
將功能分成 API 和實作子模組
針對應用程式中的每項功能,建立兩個名為 api 和 impl (「implementation」的縮寫) 的子模組。請參考下表,決定導覽程式碼的放置位置。
模組名稱 |
包含 |
|
|
|
該功能的內容,包括 |
這種方法可讓一項功能導覽至另一項功能,方法是讓其 impl 模組中包含的內容依附於另一個模組的導覽鍵,而該模組包含在該模組的 api 模組中。

使用擴充功能函式分隔導覽項目
在 Navigation 3 中,可導覽的內容是使用導覽項目定義。如要將這些項目分隔成不同的模組,請在 EntryProviderScope 上建立擴充功能函式,並將其移至該功能的 impl 模組。這些稱為項目建構工具。
以下程式碼範例顯示建構兩個導覽項目的項目建構工具。
// import androidx.navigation3.runtime.EntryProviderScope // import androidx.navigation3.runtime.NavKey fun EntryProviderScope<NavKey>.featureAEntryBuilder() { entry<KeyA> { ContentRed("Screen A") { // Content for screen A } } entry<KeyA2> { ContentGreen("Screen A2") { // Content for screen A2 } } }
在主要應用程式模組中定義 entryProvider 時,請使用 entryProvider DSL 呼叫該函式。
// import androidx.navigation3.runtime.entryProvider // import androidx.navigation3.ui.NavDisplay NavDisplay( entryProvider = entryProvider { featureAEntryBuilder() }, // ... )
使用依附元件插入功能,將項目新增至主應用程式
在上述程式碼範例中,主要應用程式會使用 entryProvider DSL 直接呼叫每個項目建構工具。如果應用程式有許多畫面或功能模組,這個模式可能無法妥善擴充。
如要解決這個問題,請使用依附元件插入,讓每個功能模組將其項目建構工具提供給應用程式的活動。
舉例來說,下列程式碼使用 Dagger 多重繫結 (具體來說是 @IntoSet),將項目建構工具插入 MainActivity 擁有的 Set。接著,系統會在 entryProvider 內反覆呼叫這些函式,因此不必明確呼叫多個項目建構工具函式。
功能模組
// import dagger.Module // import dagger.Provides // import dagger.hilt.InstallIn // import dagger.hilt.android.components.ActivityRetainedComponent // import dagger.multibindings.IntoSet @Module @InstallIn(ActivityRetainedComponent::class) object FeatureAModule { @IntoSet @Provides fun provideFeatureAEntryBuilder() : EntryProviderScope<NavKey>.() -> Unit = { featureAEntryBuilder() } }
應用程式模組
// import android.os.Bundle // import androidx.activity.ComponentActivity // import androidx.activity.compose.setContent // import androidx.navigation3.runtime.EntryProviderScope // import androidx.navigation3.runtime.NavKey // import androidx.navigation3.runtime.entryProvider // import androidx.navigation3.ui.NavDisplay // import javax.inject.Inject class MainActivity : ComponentActivity() { @Inject lateinit var entryBuilders: Set<@JvmSuppressWildcards EntryProviderScope<NavKey>.() -> Unit> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { NavDisplay( entryProvider = entryProvider { entryBuilders.forEach { builder -> this.builder() } }, // ... ) } } }
如果導覽項目需要導覽 (例如包含可導覽至新畫面的 UI 元素),請將能夠修改應用程式導覽狀態的物件插入每個建構工具函式。
模組化深層連結比對器
如果應用程式支援深層連結且已模組化,則每個功能模組都應為其擁有的目的地定義 DeepLinkMatcher 執行個體。
如要整理應用程式中的所有比對器,可以使用依附元件插入多重繫結。舉例來說,每個功能模組都可以將比對器提供給 Dagger @IntoSet 多重繫結:
功能模組
@Module @InstallIn(ActivityRetainedComponent::class) object FeatureADeepLinkModule { @IntoSet @Provides fun provideUserMatcher(): DeepLinkMatcher<*, *> { return UriDeepLinkMatcher( DeepLinkUri("www.example.com/users/{id}"), serializer<UserProfileKey>() ) } }
接著,在主要應用程式模組 (例如 MainActivity) 中,您可以插入比對器組合,並用來比對傳入的要求:
應用程式模組
@AndroidEntryPoint class MainActivityWithDI : ComponentActivity() { @Inject lateinit var deepLinkMatchers: Set<@JvmSuppressWildcards DeepLinkMatcher<*, *>> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val request = DeepLinkRequest(intent = intent) val matchResult = deepLinkMatchers .mapNotNull { it.match(request) } .maxOrNull() val backStack = when (matchResult) { null -> listOf(HomeKey) is BackStackMatchResult<*, *> -> { @Suppress("UNCHECKED_CAST") matchResult.backStack as List<NavKey> } else -> listOf(matchResult.key) } } }
如要進一步瞭解如何定義及處理深層連結,請參閱「支援深層連結」。
資源
如需程式碼範例,瞭解如何模組化 Navigation 3 程式碼,請參閱: