質感設計 3 是新一代的質感設計,這項服務 包括更新後的主題設定、元件和 Material You 個人化功能 例如動態色彩目前為質感設計 2 的更新版本, 與 Android 12 以上版本的新視覺風格和系統 UI 更加貼合。
本指南著重於從 Compose Material 遷移 (androidx.compose.material) Jetpack 程式庫至 Compose Material 3 (androidx.compose.material3) Jetpack 程式庫。
做法
一般來說,您不應在單一應用程式中長期同時使用 M2 和 M3。這個 這是因為兩個設計系統和對應的程式庫並不相同 大幅影響使用者體驗/使用者介面設計和 Compose 實作。
您的應用程式可能會使用特定設計系統,例如使用 Figma 建立的系統。因此 我們也強烈建議您或設計團隊從 M2 進行遷移 遷移至 M3。不合理地進行遷移 將應用程式更新至 M3,前提是要以 M2 進行使用者體驗/UI 設計。
此外,視應用程式 大小、複雜度和使用者體驗/使用者介面設計這樣做可以幫助您盡量減少 程式碼集建議您分階段執行遷移作業。
遷移時機
您應該盡快開始進行遷移作業。不過,您仍須確保 思考應用程式的表現是否恰當,可「全面」遷移 從 M2 到 M3有些「阻礙」的情境可供您調查, 開始前:
情境 | 建議做法 |
---|---|
沒有「阻礙者」 | 開始階段式遷移作業 |
M3 尚未提供某個 M2 的元件。詳情請參閱下方的元件和版面配置一節。 | 開始階段式遷移作業 |
您或設計團隊尚未將應用程式的設計系統從 M2 遷移至 M3 | 將設計系統從 M2 遷移至 M3,然後開始階段式遷移作業 |
即使您受到上述情境影響,仍建議您分階段實施 ,在修訂及發布應用程式更新前完成遷移。在這些情況下,您必須 會並行使用 M2 和 M3,並在遷移至以下版本時逐步停用 M2 M3:
階段式做法
階段式遷移作業的一般步驟如下:
- 新增 M3 依附元件,與 M2 依附元件並用。
- 新增應用程式主題的 M3 版本,與 M2 版本並用 應用程式主題。
- 視需要將個別模組、畫面或可組合項遷移至 M3 大小和複雜度 (詳情請參閱以下各節)。
- 完全遷移後,移除應用程式主題的 M2 版本。
- 移除 M2 依附元件。
依附元件
M3 的套件和版本與 M2 不同:
M2
implementation "androidx.compose.material:material:$m2-version"
M3
implementation "androidx.compose.material3:material3:$m3-version"
請前往 Compose 質感設計 3 版本頁面查看 M3 的最新版本。
M2 和 M3 主要程式庫以外的其他質感設計依附元件 已變更。他們混用 M2 和 M3 的套件和版本,但沒有 對遷移的影響也可直接與 M3 搭配使用:
程式庫 | 套件和版本 |
---|---|
Compose 質感設計圖示 | androidx.compose.material:material-icons-*:$m2-version |
Compose 質感設計漣漪效果 | androidx.compose.material:material-ripple:$m2-version |
Compose 質感設計 3 視窗大小類別 | androidx.compose.material3:material3-window-size-class:$m3-version |
實驗性 API
部分 M3 API 屬於實驗性質。此時,您必須透過
使用 ExperimentalMaterial3Api
註解來設定函式或檔案層級:
import androidx.compose.material3.ExperimentalMaterial3Api
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppComposable() {
// M3 composables
}
主題設定
在 M2 和 M3 中,主題可組合項的名稱都是 MaterialTheme
,但匯入作業
套件和參數並不相同:
M2
import androidx.compose.material.MaterialTheme
MaterialTheme(
colors = AppColors,
typography = AppTypography,
shapes = AppShapes
) {
// M2 content
}
M3
import androidx.compose.material3.MaterialTheme
MaterialTheme(
colorScheme = AppColorScheme,
typography = AppTypography,
shapes = AppShapes
) {
// M3 content
}
顏色
![比較 M2 和 M3 的色彩系統](https://developer.android.google.cn/static/develop/ui/compose/images/migration-color-update.png?authuser=3&hl=zh-tw)
M3 的色彩系統與 M2 有明顯差異。
顏色參數的數量增加、名稱不同
可以分別對應至 M3 元件在 Compose 中,這適用於 M2
Colors
類別、M3 ColorScheme
類別和相關函式:
M2
import androidx.compose.material.lightColors
import androidx.compose.material.darkColors
val AppLightColors = lightColors(
// M2 light Color parameters
)
val AppDarkColors = darkColors(
// M2 dark Color parameters
)
val AppColors = if (darkTheme) {
AppDarkColors
} else {
AppLightColors
}
M3
import androidx.compose.material3.lightColorScheme
import androidx.compose.material3.darkColorScheme
val AppLightColorScheme = lightColorScheme(
// M3 light Color parameters
)
val AppDarkColorScheme = darkColorScheme(
// M3 dark Color parameters
)
val AppColorScheme = if (darkTheme) {
AppDarkColorScheme
} else {
AppLightColorScheme
}
由於 M2 和 M3 色彩系統之間存在顯著差異
沒有合理的 Color
參數對應。請改為使用 Material Design
主題建構工具:可產生 M3 色彩配置。使用 M2
做為工具中的「核心」來源色彩,這項工具會擴大為色調。
M3 色彩配置使用的調色盤。建議使用下列對應做為
起點:
M2 | 質感設計主題建構工具 |
---|---|
primary |
Primary |
primaryVariant |
Secondary (次要) |
secondary |
Tertiary (第三) |
surface 或 background |
普通 |
![質感設計主題建構工具中用來產生 M3 色彩配置的 M2 色彩](https://developer.android.google.cn/static/develop/ui/compose/images/migration-colorscheme-update.png?authuser=3&hl=zh-tw)
您可以從工具複製淺色和深色主題的十六進位顏色代碼值 並使用這些範例實作 M3 ColorScheme 執行個體。Material Design 主題建構工具可匯出 Compose 程式碼。
isLight
與 M2 Colors
類別不同,M3 ColorScheme
類別不提供
isLight
參數。一般來說,請盡量使用
在主題層級提供這類資訊例如:
M2
import androidx.compose.material.lightColors
import androidx.compose.material.darkColors
import androidx.compose.material.MaterialTheme
@Composable
private fun AppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val colors = if (darkTheme) darkColors(…) else lightColors(…)
MaterialTheme(
colors = colors,
content = content
)
}
@Composable
fun AppComposable() {
AppTheme {
val cardElevation = if (MaterialTheme.colors.isLight) 0.dp else 4.dp
…
}
}
M3
import androidx.compose.material3.lightColorScheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.MaterialTheme
val LocalCardElevation = staticCompositionLocalOf { Dp.Unspecified }
@Composable
private fun AppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val cardElevation = if (darkTheme) 4.dp else 0.dp
CompositionLocalProvider(LocalCardElevation provides cardElevation) {
val colorScheme = if (darkTheme) darkColorScheme(…) else lightColorScheme(…)
MaterialTheme(
colorScheme = colorScheme,
content = content
)
}
}
@Composable
fun AppComposable() {
AppTheme {
val cardElevation = LocalCardElevation.current
…
}
}
詳情請參閱 Compose 中的自訂設計系統指南。
動態色彩
M3 的其中一項新功能是動態色彩。相較於自訂的
M3 ColorScheme
可以在 Android 上使用裝置桌布顏色
12 以上函式,並且使用下列函式:
字體排版
![比較 M2 和 M3 的字體排版系統](https://developer.android.google.cn/static/develop/ui/compose/images/migration-typography-update.png?authuser=3&hl=zh-tw)
M3 的字體排版系統與 M2 不同。開啟
字體排版參數大致相同,但名稱不同
分別對應至 M3 元件在 Compose 中,這適用於 M2
Typography
類別和 M3 Typography
類別:
M2
import androidx.compose.material.Typography
val AppTypography = Typography(
// M2 TextStyle parameters
)
M3
import androidx.compose.material3.Typography
val AppTypography = Typography(
// M3 TextStyle parameters
)
建議您使用下列 TextStyle
參數對應做為起點
點:
M2 | M3 |
---|---|
h1 |
displayLarge |
h2 |
displayMedium |
h3 |
displaySmall |
無 | headlineLarge |
h4 |
headlineMedium |
h5 |
headlineSmall |
h6 |
titleLarge |
subtitle1 |
titleMedium |
subtitle2 |
titleSmall |
body1 |
bodyLarge |
body2 |
bodyMedium |
caption |
bodySmall |
button |
labelLarge |
無 | labelMedium |
overline |
labelSmall |
形狀
![比較 M2 和 M3 的形狀系統](https://developer.android.google.cn/static/develop/ui/compose/images/migration-shape-update.png?authuser=3&hl=zh-tw)
M3 的形狀系統與 M2 不同。形狀數量
參數數量增加,名稱也不同,且分別對應至
M3 元件。在 Compose 中,這適用於 M2 Shapes
類別和
M3 Shapes
類別:
M2
import androidx.compose.material.Shapes
val AppShapes = Shapes(
// M2 Shape parameters
)
M3
import androidx.compose.material3.Shapes
val AppShapes = Shapes(
// M3 Shape parameters
)
建議您使用下列 Shape
參數對應做為起點
點:
M2 | M3 |
---|---|
無 | extraSmall |
small |
small |
medium |
medium |
large |
large |
無 | extraLarge |
元件和版面配置
M3 支援 M2 的大多數元件和版面配置。不過 以及 M2 中沒有的新項目此外,一些 M3 元件的變化版本比 M2 的同等項目還多。一般而言,M3 API 介面會盡可能與最接近的同等項目相似 在 M2 中。
由於色彩、字體排版和形狀系統都已更新,M3 元件通常會對應 與新的主題設定值不同建議您查看符記 目錄做為來源 或是用於這些對應的真相
雖然部分元件需要特別注意,但下列功能 建議您使用對應做為起點:
缺少 API:
M2 | M3 |
---|---|
androidx.compose.material.swipeable |
尚無法使用 |
替換的 API:
M2 | M3 |
---|---|
androidx.compose.material.BackdropScaffold |
沒有 M3 同等項目,請改為遷移至 Scaffold 或 BottomSheetScaffold |
androidx.compose.material.BottomDrawer |
沒有 M3 同等項目,請改為遷移至 ModalBottomSheet |
已重新命名的 API:
所有其他 API:
查看 Compose Material 3 API 的最新 M3 元件和版面配置 參考總覽,並留意版本頁面最新資訊 並更新 API
Scaffold、Snackbar 和導覽匣
![比較 M2 和 M3 含有 Snackbar 和導覽匣的 Scaffold](https://developer.android.google.cn/static/develop/ui/compose/images/migration-scaffold-update.gif?authuser=3&hl=zh-tw)
M3 的 Scaffold 與 M2 不同。在 M2 和 M3 中,主要版面配置可組合函式
名稱為 Scaffold
,但匯入套件和參數並不相同:
M2
import androidx.compose.material.Scaffold
Scaffold(
// M2 scaffold parameters
)
M3
import androidx.compose.material3.Scaffold
Scaffold(
// M3 scaffold parameters
)
M2 Scaffold
包含 backgroundColor
參數現已命名為
M3 Scaffold
中的 containerColor
:
M2
import androidx.compose.material.Scaffold
Scaffold(
backgroundColor = …,
content = { … }
)
M3
import androidx.compose.material3.Scaffold
Scaffold(
containerColor = …,
content = { … }
)
M3 中不再包含 M2 ScaffoldState
類別,因為其中包含
不再需要的 drawerState
參數。如要顯示 Snackbar,
M3 Scaffold
,請改用 SnackbarHostState
:
M2
import androidx.compose.material.Scaffold
import androidx.compose.material.rememberScaffoldState
val scaffoldState = rememberScaffoldState()
val scope = rememberCoroutineScope()
Scaffold(
scaffoldState = scaffoldState,
content = {
…
scope.launch {
scaffoldState.snackbarHostState.showSnackbar(…)
}
}
)
M3
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
snackbarHost = { SnackbarHost(snackbarHostState) },
content = {
…
scope.launch {
snackbarHostState.showSnackbar(…)
}
}
)
M2 Scaffold
中的所有 drawer*
參數都已從以下位置移除:
M3 Scaffold
。包括 drawerShape
和
drawerContent
。如要使用 M3 Scaffold
顯示導覽匣,請使用導覽匣
可組合元件 (例如 ModalNavigationDrawer
):
M2
import androidx.compose.material.DrawerValue
import
import androidx.compose.material.Scaffold
import androidx.compose.material.rememberDrawerState
import androidx.compose.material.rememberScaffoldState
val scaffoldState = rememberScaffoldState(
drawerState = rememberDrawerState(DrawerValue.Closed)
)
val scope = rememberCoroutineScope()
Scaffold(
scaffoldState = scaffoldState,
drawerContent = { … },
drawerGesturesEnabled = …,
drawerShape = …,
drawerElevation = …,
drawerBackgroundColor = …,
drawerContentColor = …,
drawerScrimColor = …,
content = {
…
scope.launch {
scaffoldState.drawerState.open()
}
}
)
M3
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.Scaffold
import androidx.compose.material3.rememberDrawerState
val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope()
ModalNavigationDrawer(
drawerState = drawerState,
drawerContent = {
ModalDrawerSheet(
drawerShape = …,
drawerTonalElevation = …,
drawerContainerColor = …,
drawerContentColor = …,
content = { … }
)
},
gesturesEnabled = …,
scrimColor = …,
content = {
Scaffold(
content = {
…
scope.launch {
drawerState.open()
}
}
)
}
)
頂端應用程式列
![比較 M2 和 M3 含有頂端應用程式列和捲動清單的 Scaffold](https://developer.android.google.cn/static/develop/ui/compose/images/migration-topbar-update.png?authuser=3&hl=zh-tw)
M3 的頂端應用程式列與 M2 中的不同。在 M2 中
和 M3,主要頂端應用程式列可組合項的名稱是 TopAppBar
,但匯入作業是
套件和參數並不相同:
M2
import androidx.compose.material.TopAppBar
TopAppBar(…)
M3
import androidx.compose.material3.TopAppBar
TopAppBar(…)
如果先前情況過,不妨考慮使用 M3 CenterAlignedTopAppBar
在 M2 TopAppBar
中將內容置中。瞭解
MediumTopAppBar
和 LargeTopAppBar
。
M3 頂端應用程式列包含新的 scrollBehavior
參數,提供不同的
功能,例如捲動查看 TopAppBarScrollBehavior
類別
大幅改變高度這可結合透過
Modifer.nestedScroll
。在 M2 TopAppBar
中,這可能由
手動變更 elevation
參數:
M2
import androidx.compose.material.AppBarDefaults
import androidx.compose.material.Scaffold
import androidx.compose.material.TopAppBar
val state = rememberLazyListState()
val isAtTop by remember {
derivedStateOf {
state.firstVisibleItemIndex == 0 && state.firstVisibleItemScrollOffset == 0
}
}
Scaffold(
topBar = {
TopAppBar(
elevation = if (isAtTop) {
0.dp
} else {
AppBarDefaults.TopAppBarElevation
},
…
)
},
content = {
LazyColumn(state = state) { … }
}
)
M3
import androidx.compose.material3.Scaffold
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
TopAppBar(
scrollBehavior = scrollBehavior,
…
)
},
content = {
LazyColumn { … }
}
)
底部導覽 / 導覽列
![比較 M2 底部導覽與 M3 導覽列](https://developer.android.google.cn/static/develop/ui/compose/images/migration-bottomnav-update.png?authuser=3&hl=zh-tw)
M2 中的底部導覽已重新命名為 中的導覽列
M3:M2 中有 BottomNavigation
和
在 M3 中則有 BottomNavigationItem
可組合函式
NavigationBar
和 NavigationBarItem
可組合項:
M2
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
BottomNavigation {
BottomNavigationItem(…)
BottomNavigationItem(…)
BottomNavigationItem(…)
}
M3
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
NavigationBar {
NavigationBarItem(…)
NavigationBarItem(…)
NavigationBarItem(…)
}
按鈕、圖示按鈕和懸浮動作按鈕 (FAB)
![比較 M2 和 M3 按鈕](https://developer.android.google.cn/static/develop/ui/compose/images/migration-buttons-update.png?authuser=3&hl=zh-tw)
M3 中的按鈕、圖示按鈕和懸浮動作按鈕 (FAB) 則與 M2 中的不同M3 提供所有 M2 按鈕可組合項:
M2
import androidx.compose.material.Button
import androidx.compose.material.ExtendedFloatingActionButton
import androidx.compose.material.FloatingActionButton
import androidx.compose.material.IconButton
import androidx.compose.material.IconToggleButton
import androidx.compose.material.OutlinedButton
import androidx.compose.material.TextButton
// M2 buttons
Button(…)
OutlinedButton(…)
TextButton(…)
// M2 icon buttons
IconButton(…)
IconToggleButton(…)
// M2 FABs
FloatingActionButton(…)
ExtendedFloatingActionButton(…)
M3
import androidx.compose.material3.Button
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconToggleButton
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.TextButton
// M3 buttons
Button(…)
OutlinedButton(…)
TextButton(…)
// M3 icon buttons
IconButton(…)
IconToggleButton(…)
// M3 FABs
FloatingActionButton(…)
ExtendedFloatingActionButton(…)
M3 也提供新的按鈕變化版本。詳情請參閱 Compose 質感設計 3 API 參考資料總覽。
切換
![比較 M2 和 M3 的切換按鈕](https://developer.android.google.cn/static/develop/ui/compose/images/migration-switch-update.png?authuser=3&hl=zh-tw)
M3 的切換按鈕與 M2 不同。在 M2 和 M3 中,
可組合項的名稱為 Switch
,但匯入套件並不相同:
M2
import androidx.compose.material.Switch
Switch(…)
M3
import androidx.compose.material3.Switch
Switch(…)
介面和高度
![比較淺色和深色主題的 M2 介面高度與 M3 介面高度](https://developer.android.google.cn/static/develop/ui/compose/images/migration-elevation-update.png?authuser=3&hl=zh-tw)
M3 的介面和高度系統與 M2 不同。有兩種類型 M3 中的高度:
- 陰影高度 (會產生與 M2 相同的陰影)
- 色調高度 (重疊色彩,為 M3 的新功能)
在 Compose 中,這適用於 M2 Surface
函式和 M3
Surface
函式:
M2
import androidx.compose.material.Surface
Surface(
elevation = …
) { … }
M3
import androidx.compose.material3.Surface
Surface(
shadowElevation = …,
tonalElevation = …
) { … }
您可以在 M2 中為兩個 shadowElevation
使用 elevation
Dp
值
和/或 M3 中的 tonalElevation
。
Surface
是多數元件的備用可組合項,因此元件
可組合函式也可能會曝露您在
。
M3 中的色調高度會取代 M2 深色中高度重疊的概念
主題 。因此,ElevationOverlay
和 LocalElevationOverlay
不存在於 M3 中,而 M2 中的 LocalAbsoluteElevation
已變更為
M3 中的 LocalAbsoluteTonalElevation
。
強調和內容 Alpha 值
![比較 M2 和 M3 的圖示和文字強調](https://developer.android.google.cn/static/develop/ui/compose/images/migration-emphasis-update.png?authuser=3&hl=zh-tw)
M3 中的強調與 M2 有明顯差異。在 M2 中,強調的是 具有特定 Alpha 值的「上方」顏色,以區分文字、 圖示。在 M3 中,現有兩種不同的做法:
- 使用「上方」顏色,以及顏色在 M3 擴展中的「變化」 色彩系統
- 為文字使用不同的字型粗細。
因此,ContentAlpha
和 LocalContentAlpha
不存在於
必須替換 M3。
建議您使用下列對應做為起點:
M2 | M3 |
---|---|
onSurface 搭配 ContentAlpha.high |
一般為 onSurface ,文字則使用 FontWeight.Medium - FontWeight.Black |
onSurface 搭配 ContentAlpha.medium |
一般為 onSurfaceVariant ,文字則使用 FontWeight.Thin - FontWeight.Normal |
onSurface 搭配 ContentAlpha.disabled |
onSurface.copy(alpha = 0.38f) |
以下範例說明如何在 M2 與 M3 中強調圖示:
M2
import androidx.compose.material.ContentAlpha
import androidx.compose.material.LocalContentAlpha
// High emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
Icon(…)
}
// Medium emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
Icon(…)
}
// Disabled emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) {
Icon(…)
}
M3
import androidx.compose.material3.LocalContentColor
// High emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface) {
Icon(…)
}
// Medium emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurfaceVariant) {
Icon(…)
}
// Disabled emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)) {
Icon(…)
}
以下範例說明如何在 M2 與 M3 中強調文字:
M2
import androidx.compose.material.ContentAlpha
import androidx.compose.material.LocalContentAlpha
// High emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
Text(…)
}
// Medium emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
Text(…)
}
// Disabled emphasis
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) {
Text(…)
}
M3
import androidx.compose.material3.LocalContentColor
// High emphasis
Text(
…,
fontWeight = FontWeight.Bold
)
// Medium emphasis
Text(
…,
fontWeight = FontWeight.Normal
)
// Disabled emphasis
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)) {
Text(
…,
fontWeight = FontWeight.Normal
)
}
背景和容器
M2 的背景在 M3 中稱為「容器」。一般來說,您可以將
M2 中的 background*
參數和 M3 中的 container*
使用相同的值。
例如:
M2
Badge(
backgroundColor = MaterialTheme.colors.primary
) { … }
M3
Badge(
containerColor = MaterialTheme.colorScheme.primary
) { … }
實用連結
如要進一步瞭解如何在 Compose 中從 M2 遷移至 M3,請參閱下列資源 其他資源
文件
範例應用程式
- Reply M3 範例應用程式
- Jetchat 範例應用程式 M2 至 M3 遷移作業
- Jetnews 範例應用程式 M2 至 M3 遷移作業
- Now in Android M3 主要應用程式 :core-designsystem 模組
影片
API 參考資料和原始碼
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- Compose 中的質感設計 2
- Compose 中的質感設計 3
- Compose 中的自訂設計系統