建構自動調整導覽功能

大多數應用程式都有幾個可透過應用程式主要導覽 UI 存取的頂層目的地。在精簡視窗 (例如標準手機螢幕) 中,目的地通常會顯示在視窗底部的導覽列中。在展開的視窗中 (例如平板電腦上的全螢幕應用程式),通常會建議在應用程式旁邊放置導覽邊欄,因為這樣一來,您在握住裝置的左右兩側時,就能更輕鬆地操作導覽控制項。

NavigationSuiteScaffold 會根據 WindowSizeClass 顯示適當的導覽 UI 可組合項,簡化導覽 UI 之間的切換作業。這包括在執行階段視窗大小變更時,動態變更 UI。預設行為是顯示下列任一 UI 元件:

  • 寬度或高度較窄,或裝置處於桌面模式時,顯示導覽列
  • 導覽邊欄 (適用所有其他內容)
圖 1. NavigationSuiteScaffold 會在精簡視窗中顯示導覽列。
圖 2. NavigationSuiteScaffold 會在展開的視窗中顯示導覽邊欄。

新增依附元件

NavigationSuiteScaffoldMaterial3 自適應導覽套件程式庫的一部分。在應用程式或模組的 build.gradle 檔案中新增程式庫依附元件:

Kotlin

implementation("androidx.compose.material3:material3-adaptive-navigation-suite")

Groovy

implementation 'androidx.compose.material3:material3-adaptive-navigation-suite'

建立鷹架

NavigationSuiteScaffold 的兩個主要部分是導覽套件項目和所選目的地的內容。您可以直接在可組合項中定義導覽套件項目,但通常會在其他位置定義這些項目,例如在列舉中:

enum class AppDestinations(     @StringRes val label: Int,     val icon: ImageVector,     @StringRes val contentDescription: Int ) {     HOME(R.string.home, Icons.Default.Home, R.string.home),     FAVORITES(R.string.favorites, Icons.Default.Favorite, R.string.favorites),     SHOPPING(R.string.shopping, Icons.Default.ShoppingCart, R.string.shopping),     PROFILE(R.string.profile, Icons.Default.AccountBox, R.string.profile), }

如要使用 NavigationSuiteScaffold,您必須追蹤目前的目的地,方法是使用 rememberSaveable

var currentDestination by rememberSaveable { mutableStateOf(AppDestinations.HOME) }

在以下範例中,navigationSuiteItems 參數 (類型 NavigationSuiteScope) 會使用其 item 函式,定義個別目的地的導覽 UI。目的地 UI 會用於導覽列、邊欄和導覽匣。如要建立導覽項目,請迴圈 AppDestinations (在前述程式碼片段中定義):

NavigationSuiteScaffold(     navigationSuiteItems = {         AppDestinations.entries.forEach {             item(                 icon = {                     Icon(                         it.icon,                         contentDescription = stringResource(it.contentDescription)                     )                 },                 label = { Text(stringResource(it.label)) },                 selected = it == currentDestination,                 onClick = { currentDestination = it }             )         }     } ) {     // TODO: Destination content. }

在目的地內容 lambda 中,使用 currentDestination 值決定要顯示哪個 UI。如果您在應用程式中使用導覽程式庫,請在此處使用該程式庫來顯示適當的目的地。只要使用 when 陳述式即可:

NavigationSuiteScaffold(     navigationSuiteItems = { /*...*/ } ) {     // Destination content.     when (currentDestination) {         AppDestinations.HOME -> HomeDestination()         AppDestinations.FAVORITES -> FavoritesDestination()         AppDestinations.SHOPPING -> ShoppingDestination()         AppDestinations.PROFILE -> ProfileDestination()     } }

變更色彩

NavigationSuiteScaffold 會在鷹架佔用的整個區域 (通常是整個視窗) 上建立 Surface。此外,結構體會繪製特定導覽 UI,例如 NavigationBar。途徑和導覽 UI 都會使用應用程式主題中指定的值,但您可以覆寫主題值。

containerColor 參數會指定途徑的顏色。預設值是色彩配置的背景顏色。contentColor 參數可指定該介面的內容顏色。預設值為 containerColor 指定的「開啟」顏色。舉例來說,如果 containerColor 使用 background 顏色,那麼 contentColor 就會使用 onBackground 顏色。如要進一步瞭解色彩系統的運作方式,請參閱「Compose 中的 Material Design 3 主題設定」。覆寫這些值時,請使用主題中定義的值,讓應用程式支援深色和淺色顯示模式:

NavigationSuiteScaffold(     navigationSuiteItems = { /* ... */ },     containerColor = MaterialTheme.colorScheme.primary,     contentColor = MaterialTheme.colorScheme.onPrimary, ) {     // Content... }

導覽 UI 會繪製在 NavigationSuiteScaffold 途徑前方。NavigationSuiteDefaults.colors() 會提供 UI 顏色的預設值,但您也可以覆寫這些值。舉例來說,如果您希望導覽列的背景為透明,但其他值為預設值,請覆寫 navigationBarContainerColor

NavigationSuiteScaffold(     navigationSuiteItems = { /* ... */ },     navigationSuiteColors = NavigationSuiteDefaults.colors(         navigationBarContainerColor = Color.Transparent,     ) ) {     // Content... }

您可以自訂導覽 UI 中的每個項目。呼叫 item 函式時,您可以傳入 NavigationSuiteItemColors 的例項。這個類別會指定導覽列、導覽邊欄和導覽抽屜中項目的顏色。也就是說,您可以為每種導覽 UI 類型使用相同的顏色,也可以根據需求變更顏色。請在 NavigationSuiteScaffold 層級定義顏色,以便為所有項目使用相同的物件例項,並呼叫 NavigationSuiteDefaults.itemColors() 函式,只覆寫您要變更的顏色:

val myNavigationSuiteItemColors = NavigationSuiteDefaults.itemColors(     navigationBarItemColors = NavigationBarItemDefaults.colors(         indicatorColor = MaterialTheme.colorScheme.primaryContainer,         selectedIconColor = MaterialTheme.colorScheme.onPrimaryContainer     ), )  NavigationSuiteScaffold(     navigationSuiteItems = {         AppDestinations.entries.forEach {             item(                 icon = {                     Icon(                         it.icon,                         contentDescription = stringResource(it.contentDescription)                     )                 },                 label = { Text(stringResource(it.label)) },                 selected = it == currentDestination,                 onClick = { currentDestination = it },                 colors = myNavigationSuiteItemColors,             )         }     }, ) {     // Content... }

自訂導覽類型

NavigationSuiteScaffold 的預設行為會根據視窗大小類別變更導覽 UI。不過,您可能會想覆寫這項行為。舉例來說,如果您的應用程式針對動態消息顯示單一大型內容窗格,則可針對展開的視窗使用永久導覽匣,但仍會在小型和中型視窗大小類別中改用預設行為:

val adaptiveInfo = currentWindowAdaptiveInfo() val customNavSuiteType = with(adaptiveInfo) {     if (windowSizeClass.isWidthAtLeastBreakpoint(WIDTH_DP_EXPANDED_LOWER_BOUND)) {         NavigationSuiteType.NavigationDrawer     } else {         NavigationSuiteScaffoldDefaults.calculateFromAdaptiveInfo(adaptiveInfo)     } }  NavigationSuiteScaffold(     navigationSuiteItems = { /* ... */ },     layoutType = customNavSuiteType, ) {     // Content... }

其他資源