將導覽程式碼模組化

本頁面提供指南,說明如何將導覽程式碼模組化。本指南旨在補充應用程式模組化的一般指南

總覽

模組化導覽程式碼是指將相關導覽鍵及其代表的內容,分別劃分成獨立模組的過程。這樣一來,您就能清楚劃分職責,並在應用程式的不同功能之間切換。

如要將導覽程式碼模組化,請按照下列步驟操作:

  • 為應用程式中的每個功能建立兩個子模組:apiimpl
  • 將各項功能的導覽鍵放入各自的 api 模組
  • 將每項功能的 entryProviders 和可導覽內容放入相關聯的 impl 模組
  • 直接或使用依附元件插入,將 entryProviders 提供給主要應用程式模組

將功能分成 API 和實作子模組

為應用程式中的每個功能建立兩個名為 apiimpl 的子模組 (簡稱「實作」)。請參考下表,決定導覽程式碼的放置位置。

模組名稱

包含

api

導覽鍵

impl

該功能的內容,包括 NavEntryentryProvider 的定義。另請參閱「將鍵解析為內容」。

這種做法可讓一個功能導覽至另一個功能,方法是允許其內容 (包含在 impl 模組中) 依附於另一個模組的導覽鍵 (包含在該模組的 api 模組中)。

功能模組依附元件圖,顯示 `impl` 模組如何依附於 `api` 模組。
圖 1. 功能模組依附元件圖,顯示實作模組如何依附於 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 元素),請將可修改應用程式導覽狀態的物件,注入每個建構函式。

資源

如需說明如何將 Navigation 3 程式碼模組化的程式碼範例,請參閱: