Compose 中的質感設計 3

Jetpack Compose 提供 Material Design 3 實作方式。 我們將打造出新一代的 Material DesignMaterial 3 包含新版主題設定, 動態色彩等 Material You 個人化功能 旨在與 Android 12 的全新視覺風格和系統 UI 相呼應 以上。

下文將說明 Material Design 3 的實作方式 以 Reply 範例應用程式為例。Reply 範例為 完全由 Material Design 3 為基礎

使用 Material Design 3 的 Reply 範例應用程式
圖 1.使用 Material Design 3 回覆範例應用程式

依附元件

如要開始在 Compose 應用程式中使用 Material 3,請新增 Compose Material 3 build.gradle 檔案的依附元件:

implementation "androidx.compose.material3:material3:$material3_version"

新增依附元件後,即可開始新增 Material Design 系統。 包括顏色、字體排版和形狀等

實驗性 API

部分 M3 API 屬於實驗性質。此時,您必須透過 使用 ExperimentalMaterial3Api 註解來設定函式或檔案層級:

// import androidx.compose.material3.ExperimentalMaterial3Api
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppComposable() {
    // M3 composables
}

Material Design 主題設定

M3 主題包含下列子系統:色彩配置字體排版形狀。自訂設定時 等值,變更就會自動反映在您產生的 M3 元件中 可用來建構應用程式

Material Design 的子系統:顏色、字體排版和形狀
圖 2.Material Design 的子系統:顏色、字體排版和形狀

Jetpack Compose 使用 M3 MaterialTheme 實作這些概念 可組合函式:

MaterialTheme(
    colorScheme = /* ...
    typography = /* ...
    shapes = /* ...
) {
    // M3 app content
}

如要為應用程式內容設定主題,請定義色彩配置、字體排版和 應用程式專屬的形狀

色彩配置

色彩配置的基礎是五組主要顏色。每個 色彩與材質 3 使用的色調 13 調色盤相關 元件。例如,這是 淺色主題的色彩配置 回覆

Reply 應用程式淺色色彩配置
圖 3.Reply 應用程式淺色色彩配置

如想進一步瞭解色彩配置和顏色角色,請前往這個網頁

產生色彩配置

雖然您可以手動建立自訂 ColorScheme,但這麼做通常比較容易 並使用品牌的來源色彩來產生相同檔案Material Design 主題 建構工具可讓您這麼做,並且視需要匯出 Compose 主題設定程式碼。系統會產生下列檔案:

  • Color.kt 包含主題的顏色,以及定義的所有角色 包括淺色和深色主題顏色

val md_theme_light_primary = Color(0xFF476810)
val md_theme_light_onPrimary = Color(0xFFFFFFFF)
val md_theme_light_primaryContainer = Color(0xFFC7F089)
// ..
// ..

val md_theme_dark_primary = Color(0xFFACD370)
val md_theme_dark_onPrimary = Color(0xFF213600)
val md_theme_dark_primaryContainer = Color(0xFF324F00)
// ..
// ..

  • Theme.kt 包含淺色和深色色彩配置和應用程式 主題。

private val LightColorScheme = lightColorScheme(
    primary = md_theme_light_primary,
    onPrimary = md_theme_light_onPrimary,
    primaryContainer = md_theme_light_primaryContainer,
    // ..
)
private val DarkColorScheme = darkColorScheme(
    primary = md_theme_dark_primary,
    onPrimary = md_theme_dark_onPrimary,
    primaryContainer = md_theme_dark_primaryContainer,
    // ..
)

@Composable
fun ReplyTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    val colorScheme =
        if (!darkTheme) {
            LightColorScheme
        } else {
            DarkColorScheme
        }
    MaterialTheme(
        colorScheme = colorScheme,
        content = content
    )
}

如要支援淺色和深色主題,請使用 isSystemInDarkTheme()。根據 系統設定,定義要使用的色彩配置:淺色或深色。

動態色彩配置

動態色彩是 Material You 的關鍵部分,其中 演算法會從使用者的桌布衍生自訂色彩,並套用至 應用程式和系統 UI這個調色盤是用來做為生成的起點 淺色和深色色彩配置。

回覆範例應用程式為桌布 (左側) 和預設的應用程式主題設定 (右側)
圖 4. 回覆範例應用程式為桌布 (左側) 和預設的應用程式主題設定 (右側)

動態色彩適用於 Android 12 以上版本。如有動態顏色可用,您可以設定動態 ColorScheme。否則,您應該 使用自訂的淺色或深色 ColorScheme

ColorScheme 提供建構工具函式,用於建立動態光源深色色彩配置:

// Dynamic color is available on Android 12+
val dynamicColor = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
val colors = when {
    dynamicColor && darkTheme -> dynamicDarkColorScheme(LocalContext.current)
    dynamicColor && !darkTheme -> dynamicLightColorScheme(LocalContext.current)
    darkTheme -> DarkColorScheme
    else -> LightColorScheme
}

顏色用途

您可以透過以下方式存取應用程式中的 Material Design 主題色彩: MaterialTheme.colorScheme:

Text(
    text = "Hello theming",
    color = MaterialTheme.colorScheme.primary
)

每個顏色角色都可以用在各種位置,具體取決於元件用途 狀態、顯著性和強調效果

  • Primary 是基本顏色,用於主要元件,例如顯眼 按鈕、啟用狀態,以及升高表面的色調。
  • 次要主要顏色用於 UI 中較不顯眼的元件,例如 ,並拓展色彩運算式的機會。
  • 第三主要顏色是用來衍生出對比 可用於平衡主要和次要顏色,或增強 注意力層

Reply 範例應用程式設計會在頂端採用 on-primary-container color main-container。

主要容器和文字欄位具有 on-primary-container 色彩。
圖 5.主要容器和文字欄位的 on-primary-container 顏色。

Card(
    colors = CardDefaults.cardColors(
        containerColor =
        if (isSelected) MaterialTheme.colorScheme.primaryContainer
        else
            MaterialTheme.colorScheme.surfaceVariant
    )
) {
    Text(
        text = "Dinner club",
        style = MaterialTheme.typography.bodyLarge,
        color =
        if (isSelected) MaterialTheme.colorScheme.onPrimaryContainer
        else MaterialTheme.colorScheme.onSurface,
    )
}

在這裡,您可以在回覆導覽匣中查看次要和第三 容器顏色則會用於培養強調效果和強調色。

懸浮動作按鈕的 Tertiary-容器和第三容器組合。
圖 6.懸浮動作按鈕的 Tertiary-容器和第三容器組合。

字體排版

Material Design 3 定義了輸入比例 (包括文字樣式) 採用自 Material Design 2 調整設計我們已提供命名與分組功能 簡化作業:顯示、大標題、標題、內文和標籤,具有大、中等 和兩種尺寸都有小尺碼

Material Design 3 的預設字體排版縮放比例
圖 7.Material Design 3 的預設字體排版縮放比例
M3 預設字型大小/行高
displayLarge Roboto 57/64
displayMedium Roboto 45/52
displaySmall Roboto 36/44
headlineLarge Roboto 32/40
headlineMedium Roboto 28/36
headlineSmall Roboto 24/32
titleLarge New- Roboto Medium 22/28
titleMedium Roboto Medium 16/24
titleSmall Roboto Medium 14/20
bodyLarge Roboto 16/24
bodyMedium Roboto 14/20
bodySmall Roboto 12/16
labelLarge Roboto Medium 14/20
labelMedium Roboto Medium 12/16
labelSmall New Roboto Medium, 11/16

定義字體排版

Compose 提供 M3 Typography 類別,以及現有的 TextStyle字型相關類別 — 建立 Material 3 類型的模型 規模。Typography 建構函式提供每種樣式的預設值,因此您可以省略 您不想自訂的任何參數:

val replyTypography = Typography(
    titleLarge = TextStyle(
        fontWeight = FontWeight.SemiBold,
        fontSize = 22.sp,
        lineHeight = 28.sp,
        letterSpacing = 0.sp
    ),
    titleMedium = TextStyle(
        fontWeight = FontWeight.SemiBold,
        fontSize = 16.sp,
        lineHeight = 24.sp,
        letterSpacing = 0.15.sp
    ),
    // ..
)
// ..

內文大、主體媒介和標籤媒介,使用不同的字體排版。
圖 8.內文大、機體和標籤媒介,使用不同的字體排版。

您的產品不一定要使用 Material Design 的 15 個預設樣式 輸入比例這個範例中縮減了五種大小 則省略。

您可以變更 TextStyle 的預設值,自訂字體排版 和字型相關屬性,例如 fontFamilyletterSpacing

bodyLarge = TextStyle(
    fontWeight = FontWeight.Normal,
    fontFamily = FontFamily.SansSerif,
    fontStyle = FontStyle.Italic,
    fontSize = 16.sp,
    lineHeight = 24.sp,
    letterSpacing = 0.15.sp,
    baselineShift = BaselineShift.Subscript
),

定義 Typography 後,請將其傳遞至 M3 MaterialTheme

MaterialTheme(
    typography = replyTypography,
) {
    // M3 app Content
}

使用文字樣式

您可以透過下列方式擷取提供給 M3 MaterialTheme 可組合項的字體排版: 使用 MaterialTheme.typography

Text(
    text = "Hello M3 theming",
    style = MaterialTheme.typography.titleLarge
)
Text(
    text = "you are learning typography",
    style = MaterialTheme.typography.bodyMedium
)

如要進一步瞭解 Material Design 指南的申請方式,請按這裡 字體排版

形狀

Material 表面可用不同形狀顯示。形狀有助吸引註意力 識別元件、傳達狀態及呈現品牌風格

形狀比例會定義容器邊角的樣式,並提供一系列 四捨五入到全圓形。

定義形狀

Compose 提供 M3 Shapes 類別,其中包含支援的擴充參數。 全新 M3 形狀。M3 形狀比例與輸入比例類似。 可在 UI 中啟用形式多樣的形狀。

形狀大小各有不同:

  • 特小
  • 特大

根據預設,每個形狀都有預設值,但您可以覆寫這些形狀:

val replyShapes = Shapes(
    extraSmall = RoundedCornerShape(4.dp),
    small = RoundedCornerShape(8.dp),
    medium = RoundedCornerShape(12.dp),
    large = RoundedCornerShape(16.dp),
    extraLarge = RoundedCornerShape(24.dp)
)

定義 Shapes 後,即可將其傳遞至 M3 MaterialTheme

MaterialTheme(
    shapes = replyShapes,
) {
    // M3 app Content
}

使用形狀

您可以為 MaterialTheme 中的所有元件自訂形狀比例,或是 可以按元件個別執行

套用中型和大型形狀,並使用預設值:

Card(shape = MaterialTheme.shapes.medium) { /* card content */ }
FloatingActionButton(
    shape = MaterialTheme.shapes.large,
    onClick = {
    }
) {
    /* fab content */
}

Reply 範例應用程式中,資訊卡的中型形狀,以及「懸浮動作」按鈕的大型形狀。
圖 9.Reply 範例應用程式中的資訊卡形狀為中型,以及「懸浮動作」按鈕的大型形狀

另外還有兩個形狀:RectangleShapeCircleShape。 這都要歸功於 Compose矩形區域不含框線半徑,圓形則會顯示完整 有圓框的邊緣:

Card(shape = RectangleShape) { /* card content */ }
Card(shape = CircleShape) { /* card content */ }

下例示範如何使用預設形狀值的部分元件 已套用:

所有 Material 3 元件的預設形狀值。
圖 10.所有 Material 3 元件的預設形狀值。

如要進一步瞭解 Material Design 指南的申請方式,請按這裡 形狀

強調效果

M3 中的強調效果會以顏色變化與色彩呈現 組合。在 M3 中,您可以透過兩種方式在 UI 中新增強調效果:

  • 搭配使用表面、surface-variant 和背景,以及 on-surface 擴充 M3 色彩系統的 on-surface-variants 顏色。例如: 介面可與 on-surface-variant 和 surface-variant 搭配使用 提供不同層級的強調效果
,瞭解如何調查及移除這項存取權。
使用中性色彩組合來強調效果。
圖 11.使用中性色彩組合來強調效果。
  • 為文字使用不同的字型粗細。上面的重點是 自訂權重 來提供不同的強調效果

bodyLarge = TextStyle(
    fontWeight = FontWeight.Bold
),
bodyMedium = TextStyle(
    fontWeight = FontWeight.Normal
)

高度

Material 3 主要使用色調色彩重疊來表示高度。這是一項新的 以區分容器和表面的方法,增加色調 除了陰影之外,高度會使用更顯眼的色調。

搭配陰影高度的色調高度
圖 12.搭配陰影高度的色調高度

深色主題中的高度重疊在 Google 服務中也已改為色調色彩重疊 Material 3:重疊顏色來自主要色彩運算單元。

Material Design 3 中的陰影高度與色調高度
圖 13.Material Design 3 中的陰影高度與色調高度

M3 介面 (多數 M3 元件背後的備用可組合項), 包括支援色調與陰影高度:

Surface(
    modifier = Modifier,
    tonalElevation = /*...
    shadowElevation = /*...
) {
    Column(content = content)
}

Material 元件

Material Design 提供豐富的 Material 元件 (例如按鈕、方塊、資訊卡、導覽列) 已採用 Material Design 設定主題和協助製作精美的 Material Design 應用程式。您可以開始使用 內建預設屬性的元件

Button(onClick = { /*..*/ }) {
    Text(text = "My Button")
}

M3 提供多種相同元件的版本,可在不同角色中使用 採用的架構

按鈕強調來自懸浮動作按鈕 (FAB),「Primary down to Text」按鈕
圖 14.按鈕強調來自懸浮動作按鈕 (FAB),「Primary down to Text」按鈕
  • 用於最高強調動作的延伸懸浮動作按鈕:

ExtendedFloatingActionButton(
    onClick = { /*..*/ },
    modifier = Modifier
) {
    Icon(
        imageVector = Icons.Default.Edit,
        contentDescription = stringResource(id = R.string.edit),
    )
    Text(
        text = stringResource(id = R.string.add_entry),
    )
}

  • 填滿高強調動作的實心按鈕:

Button(onClick = { /*..*/ }) {
    Text(text = stringResource(id = R.string.view_entry))
}

  • 低強調動作的文字按鈕:

TextButton(onClick = { /*..*/ }) {
    Text(text = stringResource(id = R.string.replated_articles))
}

進一步瞭解 Material 按鈕和其他元件。 Material 3 提供各式各樣的元件套件,例如按鈕、App 列、導覽元件,專為不同用途而設計 手機殼和螢幕大小

Material Design 也提供多個導覽元件,可協助您實作 根據不同的螢幕大小和狀態 提供不同的導覽介面

如果要指定 5 個以下的規模較小的裝置,系統會使用 NavigationBar 目的地:

NavigationBar(modifier = Modifier.fillMaxWidth()) {
    Destinations.entries.forEach { replyDestination ->
        NavigationBarItem(
            selected = selectedDestination == replyDestination,
            onClick = { },
            icon = { }
        )
    }
}

NavigationRail 適用於中小型平板電腦或 橫向模式。提供符合人體工學的擴充功能,提升使用者體驗 裝置。

NavigationRail(
    modifier = Modifier.fillMaxHeight(),
) {
    Destinations.entries.forEach { replyDestination ->
        NavigationRailItem(
            selected = selectedDestination == replyDestination,
            onClick = { },
            icon = { }
        )
    }
}

回覆 BottomNavigationBar(左) 和 NavigationRail(右) 的展示情況
圖 15.回覆展示的BottomNavigationBar (左圖) 和NavigationRail (右圖)

使用這兩種預設主題設定回覆,為所有人提供沉浸式的使用者體驗 裝置大小

NavigationDrawer適用於您擁有的中大型平板電腦 有足夠的空間可以顯示細節您可以同時使用 PermanentNavigationDrawerModalNavigationDrawerNavigationRail

PermanentNavigationDrawer(modifier = Modifier.fillMaxHeight(), drawerContent = {
    Destinations.entries.forEach { replyDestination ->
        NavigationRailItem(
            selected = selectedDestination == replyDestination,
            onClick = { },
            icon = { },
            label = { }
        )
    }
}) {
}

永久性導覽匣回覆展示
圖 16.固定式導覽匣回覆展示

導覽選項可提升使用者體驗、人體工學和可連性。 如要進一步瞭解 Material 導覽元件,請參閱 Compose 自動調整式程式碼研究室

自訂元件的主題設定

M3 有助於提供個人化體驗和彈性。所有元件均有預設值 但會公開靈活的 API 來自訂顏色 這通常代表交易 不會十分要求關聯語意

多數元件 (例如資訊卡和按鈕) 都提供預設曝光顏色的物件 和高度介面,可以修改元件來自訂元件:

val customCardColors = CardDefaults.cardColors(
    contentColor = MaterialTheme.colorScheme.primary,
    containerColor = MaterialTheme.colorScheme.primaryContainer,
    disabledContentColor = MaterialTheme.colorScheme.surface,
    disabledContainerColor = MaterialTheme.colorScheme.onSurface,
)
val customCardElevation = CardDefaults.cardElevation(
    defaultElevation = 8.dp,
    pressedElevation = 2.dp,
    focusedElevation = 4.dp
)
Card(
    colors = customCardColors,
    elevation = customCardElevation
) {
    // m3 card content
}

進一步瞭解如何自訂 Material 3

系統 UI

Material You 的部分功能來自新的視覺風格和系統 UI 搭載 Android 12 以上版本。兩個主要部分是漣漪效果 過度捲動您無須採取額外工作即可導入這些變更。

漣漪

按下時,分享關係圖現在使用細微的火花來照亮途徑。 Compose Material Ripple 會在內部使用平台 RippleDrawable Android 顯示,Android 12 以上版本支援所有 Material 的火花分享關係圖 元件。

M2 與 M3 的漣漪效果
圖 17.M2 與 M3 的漣漪效果

過度捲動

過度捲動現在可以在捲動容器的邊緣使用延展效果。 根據預設,捲動容器可組合函式會啟用延展過度捲動功能。 例如 LazyColumnLazyRowLazyVerticalGrid Compose Foundation 1.1.0 以上版本 (無論 API 級別為何)。

在容器邊緣使用延展效果進行過度捲動
圖 18.在容器邊緣使用延展效果進行過度捲動

無障礙設定

Material 元件內建的無障礙標準旨在 打響多元包容產品的設計基礎瞭解產品 讓所有使用者都能使用無障礙設計 視力, 失明, 聽障, 認知障礙, 動作 身心障礙或情境障礙 (例如手臂破裂)。

顏色無障礙功能

動態色彩設計符合無障礙色彩對比的無障礙標準。 色調調色盤系統是讓任何色彩配置更容易取用的關鍵 根據預設。

Material 的色彩系統提供標準色調值和測量結果, 才能達到無障礙的對比率

Reply 範例應用程式:主要、次要和第三色調調色盤 (由上至下)
圖 19.Reply 範例應用程式:主要、次要和第三色調調色盤 (由上至下)

所有 Material 元件和動態主題設定都已使用上述顏色角色 一組色調調色盤,其中選出符合無障礙需求的選項 Google Cloud 就是最佳選擇不過,如要自訂元件,請務必使用 適當的顏色角色,避免不相符

在 primary 上使用 on-primary,在主要基礎架構上使用 on-primary-container 同樣用於提供其他強調色和中性色的主色容器 方便使用者對比。

在主要容器上方使用第三種容器,會讓使用者感覺很差 對比按鈕:

// ✅ Button with sufficient contrast ratio
Button(
    onClick = { },
    colors = ButtonDefaults.buttonColors(
        containerColor = MaterialTheme.colorScheme.primary,
        contentColor = MaterialTheme.colorScheme.onPrimary
    )
) {
}

// ❌ Button with poor contrast ratio
Button(
    onClick = { },
    colors = ButtonDefaults.buttonColors(
        containerColor = MaterialTheme.colorScheme.tertiaryContainer,
        contentColor = MaterialTheme.colorScheme.primaryContainer
    )
) {
}

充分對比 (左側) 與對比不佳 (右側)
圖 20.充分對比 (左側) 與低對比 (右側)

字體排版無障礙功能

M3 輸入比例會更新靜態類型坡道和值,提供更加簡化的 而是可因應各種裝置調整為適合的尺寸類別動態架構。

舉例來說,在 M3 中,系統可能會根據 貼在手機或平板電腦等裝置情境上

大螢幕

Material Design 提供自動調整式版面配置和摺疊式裝置的相關指引,協助您建構應用程式 讓擁有大型裝置的使用者能享有更便利的存取體驗。

Material Design 提供多種導覽功能, 可為大型裝置提供更優質的使用者體驗。

您可以進一步瞭解 Android 大螢幕應用程式品質指南,以及 請參閱 Reply 範例,瞭解自動調整式和無障礙設計。

瞭解詳情

如要進一步瞭解 Compose 中的 Material Design 主題設定,請參閱下列資源 資源:

範例應用程式

文件

API 參考資料和原始碼

影片