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
@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 淺色主題的色彩配置:

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。這個調色盤是用來做為產生淺色和深色配置的起點。

從桌布 (左圖) 和預設應用程式主題 (右圖) 套用 Reply 範例應用程式的動態主題設定
圖 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」範例應用程式設計會在 primary-container 上方使用 on-primary-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.適用於懸浮動作按鈕的三級容器和在三級容器上的組合。

字體排版

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
}

使用文字樣式

您可以使用 MaterialTheme.typography 擷取提供給 M3 MaterialTheme 可組合項的字體排版:

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

如要進一步瞭解 Material 指南,請參閱「套用字體排版」一文。

形狀

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 */
}

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

在 Compose 中,您還可以使用另外兩種形狀:RectangleShapeCircleShape。矩形區域不含框線半徑,圓形則會顯示完整 有圓框的邊緣:

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 可與 on-surface 搭配使用,藉此提供不同程度的強調效果。
使用中性色彩組合來強調效果。
圖 11. 使用中性色彩組合來強調效果。
  • 為文字使用不同的字型粗細。上面的重點是 自訂權重 來提供不同的強調效果

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

高度

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

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

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

Material Design 3 中的陰影高度與色調高度
圖 13。Material Design 3 中的陰影高度與色調高度比較

M3 Surface 是大多數 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 提供多種元件套件,例如按鈕、應用程式列、導覽元件,這些元件專為不同用途和螢幕大小而設計。

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

NavigationBar 適用於小型裝置,可用於指定 5 個或以下的目標:

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 Design 導覽元件,請參閱 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 的某些面向,來自 Android 12 以上版本的全新視覺樣式和系統 UI。兩個主要部分是漣漪效果 過度捲動您無須採取額外工作就能導入這些變更。

漣漪

按下時,分享關係圖現在使用細微的火花來照亮途徑。 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 元件和動態主題設定都已使用上述顏色角色,這些角色來自一組色調調色盤,是為了滿足無障礙需求而選取。不過,如要自訂元件,請務必使用 適當的顏色角色,避免不相符

在 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 參考資料和原始碼

影片