Android Dark Theme 深色模式實戰
支援深色模式 (Dark Mode) 是現代 App 的基本要求。良好的深色模式不僅是將背景變黑,更關乎視覺對比度、可讀性以及在低光源環境下的使用者舒適度。在 Jetpack Compose 中,透過 Material 3 的色彩系統,這一切都變得非常直觀。
核心機制:偵測與套用
Compose 透過 isSystemInDarkTheme() 偵測系統層級的設定,並在自定義的 Theme 中切換色彩配置。
@Composable
fun MyApplicationTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
// Android 12+ 支援動態色彩 (由使用者桌布衍生)
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkColorScheme
else -> LightColorScheme
}
MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
content = content
)
}
語意化色彩 (Semantic Colors)
在開發時,絕對不要使用硬編碼顏色(如 Color.White 或 Color.Black)。你應該始終從 MaterialTheme.colorScheme 中選取具有「語意」的變數,這樣系統才能自動在兩種模式間切換。
常用的語意化色彩對應:
| 語意變數 | 用途描述 | 淺色模式表現 | 深色模式表現 |
|---|---|---|---|
primary | 主要品牌顏色 | 明亮主要色 | 較淺/柔和的主色 |
onPrimary | 在主色上的文字/圖示 | 白色或深色 | 通常是極深色 |
surface | 卡片、選單、對話框背景 | 白色/淺灰色 | 深灰色 |
onSurface | 在 Surface 上的主文字 | 深灰色/黑色 | 白色/淺灰色 |
error | 錯誤訊息或提示 | 紅色 | 較亮的珊瑚紅 |
// ✅ 正確寫法:系統會根據主題自動切換顏色
Surface(
color = MaterialTheme.colorScheme.background,
contentColor = MaterialTheme.colorScheme.onBackground
) {
Text("這是自適應文字")
}
// ❌ 錯誤寫法:在深色模式下會導致黑色背景配黑色文字(看不見)
Text("硬編碼文字", color = Color.Black)
圖示與圖片的處理
圖示染色 (Tinting)
大多數系統圖示應隨主題切換顏色。你可以直接存取 LocalContentColor 或語意顏色。
Icon(
imageVector = Icons.Default.Favorite,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary // 圖示會隨主題變色
)
圖片亮度過濾
有些圖片在全黑背景下可能顯得過於刺眼。你可以視情況在深色模式下降低圖片的透明度或亮度。
Image(
painter = painterResource(id = R.drawable.my_image),
contentDescription = null,
alpha = if (isSystemInDarkTheme()) 0.8f else 1.0f // 深色模式下稍微調暗
)
測試與多重預覽 (Multi-Preview)
你可以透過多重 @Preview 註解,一次檢視頁面在不同模式下的呈現狀況。
@Preview(name = "淺色模式", showBackground = true)
@Preview(
name = "深色模式",
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_YES
)
@Composable
fun GreetingPreview() {
MyApplicationTheme {
Greeting("Android")
}
}
總結
深色模式的核心在於「語意化」。只要在專案初期就養成使用 MaterialTheme.colorScheme 的習慣,你的 App 就能自動獲得高品質的深色主題支援。記住:深色模式應著重於降低眼睛疲勞,而非單純的顏色反轉。