Compose 中的質感設計 3

Jetpack Compose 可讓您實作 Material You 和 Material 3 Expressive,這是新一代的 Material Design。M3 Expressive 是 Material Design 3 的擴展版本,包含根據研究結果更新的主題、元件、動態效果、排版等,協助您打造使用者喜愛的吸引人產品。還支援動態色彩等 Material You 個人化功能。M3 Expressive 與 Android 16 視覺風格和系統 UI 相輔相成。

以下以 Reply 範例應用程式為例,說明如何實作 Material Design 3。Reply 範例完全以 Material Design 3 為基礎。

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

依附元件

如要在 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 }

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

色彩配置

色彩配置的基礎是五組主要顏色。每種顏色都與 13 種色調的色調調色盤相關,這些色調會用於 Material 3 元件。舉例來說,以下是「回覆」的淺色主題色彩配置:

回覆範例應用程式的淺色色彩配置
圖 3. Reply 範例應用程式淺色色彩配置

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

產生色彩配置

雖然您可以手動建立自訂 ColorScheme,但使用品牌的來源色彩來產生這個類別是較容易的方式。您可以使用材質主題建構工具來執行這項操作,並視需要匯出 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. Reply 範例應用程式的動態主題設定 (左側) 和預設應用程式主題設定 (右側)

動態色彩適用於 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 }

顏色使用方式

您可以在應用程式中透過 MaterialTheme.colorScheme 存取 Material Design 主題顏色:

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-container」和「on-tertiary-container」組合。
圖 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. 回覆範例應用程式中的「回覆」動作按鈕和「回覆」資訊卡的中型和大型形狀

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

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

以下範例展示部分套用預設形狀值的元件:

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

如要進一步瞭解 Material 指南,請參閱套用形狀

強調效果

M3 中的強調效果會使用各種顏色變化及其色彩組合。在 M3 中,有兩種方式可強調 UI:

  • 使用表面、surface-variant 和背景,搭配已擴充 M3 色彩系統的 on-surface、on-surface-variants 顏色。舉例來說,表面可與 on-surface-variant 搭配使用,surface-variant 可與 on-surface 搭配使用,藉此提供不同程度的強調效果。
使用中性色組合來強調。
圖 11. 使用中性色組合來強調。
  • 為文字使用不同的字型粗細。如上所示,您可以為輸入比例提供自訂粗細,以達到不同的強調效果。

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

高度

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

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

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

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

M3 Surface 是大多數 M3 元件的備用可組合函式,同時支援色調及陰影高度:

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

Material 元件

Material Design 隨附豐富的Material Design 元件 (例如按鈕、晶片、資訊卡、導覽列),這些元件已遵循 Material Design 主題設定,可協助您打造美觀的 Material Design 應用程式。您可以直接使用預設屬性的元件。

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

M3 提供許多相同元件的版本,可根據強調效果和注意力,用於不同角色。

按鈕的強調程度從懸浮動作按鈕、主要按鈕到文字按鈕
圖 14. 按鈕強調程度從懸浮動作按鈕、主要按鈕到文字按鈕
  • 強調程度最高的動作:

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 也提供多種導覽元件,可協助您根據不同的螢幕大小和狀態實作導覽功能。

如要指定最多 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 = { }         )     } }

Reply 示範 BottomNavigationBar(左) 和 NavigationRail(右)
圖 15. 回覆展示櫃 (左側為 BottomNavigationBar,右側為 NavigationRail)

使用預設主題回覆,為所有裝置尺寸提供沉浸式使用者體驗。

NavigationDrawer 適用於中型到大型平板電腦,這類裝置有足夠空間顯示詳細資料。您可以同時使用 PermanentNavigationDrawerModalNavigationDrawerNavigationRail

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

回覆:固定式導覽匣展示
圖 16. Reply 應用程式的固定式導覽匣展示

導覽選項可提升使用者體驗、人體工學和可及性。 如要進一步瞭解 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 分享關係圖在 Android 手機使用平台 RippleDrawable,因此 Android 12 以上版本所有材質元件均可使用火花分享關係圖。

M2 和 M3 中的 Ripple
圖 17. M2 與 M3 的漣漪效果

過度捲動

過度捲動現在可以在捲動容器的邊緣使用延展效果。就 Compose Foundation 1.1.0 以上版本而言,無論 API 級別為何,延伸過度捲動設定在捲動容器可組合項中皆預設為開啟,例如 LazyColumnLazyRow 以及 LazyVerticalGrid

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

無障礙設定

質感設計元件內建無障礙標準,可為包容性產品設計奠定基礎。瞭解產品的無障礙功能,有助於提升所有使用者的易用性,包括視力不佳、失明、聽障、認知障礙、運動障礙或情境障礙 (例如手臂骨折) 的使用者。

顏色無障礙功能

動態色彩的設計符合色彩對比度的無障礙標準。色調調色盤系統是預設建立無障礙色彩配置的關鍵。

Material 的色彩系統提供標準的色調值和測量方法,可用於達到一目瞭然的對比度。

回覆範例應用程式:原色、二次色和三次色調色盤 (由上到下)
圖 19. 回覆範例應用程式:原色、二次色及三次色調色盤 (由上而下)

所有 Material 元件和動態主題設定都已使用上述色彩角色,這些角色來自一組色調調色盤,可滿足無障礙需求。不過,如果您要自訂元件,請務必使用適當的顏色角色,避免不符。

在原色上使用 on-primary,在 primary-container 上使用 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 中,Display Small 可根據裝置情境 (例如手機或平板電腦) 指派不同的值。

大螢幕

Material Design 提供有關適應性版面配置和折疊式裝置的指南,協助您提升應用程式的無障礙程度,並改善使用者握持大型裝置時的人體工學體驗。

Material 提供不同類型的導覽,協助您為大型裝置提供更優質的使用者體驗。

如要進一步瞭解 Android 大螢幕應用程式品質指南,請參閱我們的回覆範例,瞭解如何設計可自動調整大小且無障礙的應用程式。

瞭解詳情

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

範例應用程式

文件

API 參考資料和原始碼

影片