Android 入门教程
Compose 主题与样式
本教程共 100 篇 · 第 50 篇 · 更新于 2026-07-28 · 约 8 分钟阅读
AndroidAndroid 入门教程Jetpack ComposeMaterialTheme主题暗色模式动态颜色
50. Compose 主题与样式
本节目标:理解 Compose 的主题系统,学会自定义颜色、字体、形状,实现暗色主题切换和 Android 12+ 动态颜色。
MaterialTheme 三要素
Compose 用 MaterialTheme 统一管理视觉风格。它包含三个核心维度:
- ColorScheme(颜色方案):背景色、文字色、主色等
- Typography(字体排版):各种文字样式
- Shapes(形状):组件圆角
打个比方:主题像装修方案。颜色方案是墙漆和家具配色,字体排版是各房间门牌大小,形状是门窗的圆角风格。改一个主题,整个房子风格统一变化。
基本用法
@Composable
fun MyAppTheme(content: @Composable () -> Unit) {
MaterialTheme(
colorScheme = lightColorScheme(),
typography = Typography(),
shapes = Shapes(),
content = content
)
}
在应用内通过 MaterialTheme.colorScheme、MaterialTheme.typography、MaterialTheme.shapes 访问。
ColorScheme 颜色方案
Material 3 定义了一组语义化颜色角色:
private val LightColors = lightColorScheme(
primary = Color(0xFF0066CC),
onPrimary = Color.White,
primaryContainer = Color(0xFFD1E4FF),
onPrimaryContainer = Color(0xFF001D36),
secondary = Color(0xFF535F70),
background = Color(0xFFFDFCFF),
onBackground = Color(0xFF1A1C1E),
surface = Color(0xFFFDFCFF),
onSurface = Color(0xFF1A1C1E),
error = Color(0xFFBA1A1A)
)
private val DarkColors = darkColorScheme(
primary = Color(0xFF9ECAFF),
onPrimary = Color(0xFF003258),
background = Color(0xFF1A1C1E),
onBackground = Color(0xFFE2E2E5),
surface = Color(0xFF1A1C1E),
onSurface = Color(0xFFE2E2E5),
error = Color(0xFFFFB4AB)
)
关键颜色角色:
| 颜色 | 含义 |
|---|---|
primary / onPrimary | 主色 / 主色上的文字色 |
primaryContainer / onPrimaryContainer | 主色容器 / 容器内文字 |
background / onBackground | 背景色 / 背景上文字 |
surface / onSurface | 表面色 / 表面文字 |
error / onError | 错误色 |
Note
- 每个颜色都有配对的
on颜色。primary是按钮背景,onPrimary是按钮文字。配对使用才能保证对比度足够。
使用颜色
Text(
"文字",
color = MaterialTheme.colorScheme.onSurface
)
Button(onClick = { }) {
Text("按钮") // 自动用 onPrimary 色
}
Typography 字体排版
定义不同文字级别样式:
val AppTypography = Typography(
headlineLarge = TextStyle(
fontSize = 32.sp,
fontWeight = FontWeight.Bold,
lineHeight = 40.sp
),
titleLarge = TextStyle(
fontSize = 22.sp,
fontWeight = FontWeight.SemiBold,
lineHeight = 28.sp
),
bodyLarge = TextStyle(
fontSize = 16.sp,
fontWeight = FontWeight.Normal,
lineHeight = 24.sp
),
bodyMedium = TextStyle(
fontSize = 14.sp,
lineHeight = 20.sp
),
labelLarge = TextStyle(
fontSize = 14.sp,
fontWeight = FontWeight.Medium
)
)
使用:
Text(
"标题",
style = MaterialTheme.typography.titleLarge
)
Text(
"正文内容",
style = MaterialTheme.typography.bodyMedium
)
Tip
- 别到处硬编码
fontSize和color。用MaterialTheme.typography统一管理,改一处全局生效,风格一致。
Shapes 形状
val AppShapes = Shapes(
small = RoundedCornerShape(4.dp),
medium = RoundedCornerShape(8.dp),
large = RoundedCornerShape(16.dp)
)
组件自动按尺寸用对应的形状:小按钮用 small,卡片用 medium,底部弹层用 large。
Card(shape = MaterialTheme.shapes.medium) { /* ... */ }
暗色主题
根据系统设置切换明暗主题:
@Composable
fun MyAppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val colors = if (darkTheme) DarkColors else LightColors
MaterialTheme(
colorScheme = colors,
typography = AppTypography,
shapes = AppShapes,
content = content
)
}
isSystemInDarkTheme() 自动读取系统暗色模式设置。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyAppTheme {
AppContent()
}
}
}
}
Note
- 只要你的界面都用了
MaterialTheme.colorScheme的颜色,明暗主题切换是自动的—不需要给每个组件写两套颜色。
动态颜色(Dynamic Color)
Android 12+ 支持动态颜色,系统根据壁纸自动生成配色:
@Composable
fun MyAppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val context = LocalContext.current
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
if (darkTheme) dynamicDarkColorScheme(context)
else dynamicLightColorScheme(context)
}
darkTheme -> DarkColors
else -> LightColors
}
MaterialTheme(
colorScheme = colorScheme,
content = content
)
}
Tip
- 动态颜色让应用融入用户壁纸的色调,视觉更统一。Android 12+ 默认开启,低版本回退到你定义的固定配色。这是 Material You 的核心特性。
状态栏颜色
@Composable
fun MyAppTheme(content: @Composable () -> Unit) {
val darkTheme = isSystemInDarkTheme()
val systemUiController = rememberSystemUiController()
SideEffect {
systemUiController.setSystemBarsColor(
color = Color.Transparent,
darkIcons = !darkTheme
)
}
MaterialTheme(
colorScheme = if (darkTheme) DarkColors else LightColors,
content = content
)
}
Warning
rememberSystemUiController()来自accompanist-systemuicontroller库。较新版本 Compose 可以直接用WindowCompat设置状态栏外观。
完整主题文件
实际项目里,主题通常拆成单独文件 ui/theme/Theme.kt、Color.kt、Type.kt:
// Color.kt
val md_primary = Color(0xFF0066CC)
val md_onPrimary = Color.White
// Type.kt
val AppTypography = Typography(
bodyLarge = TextStyle(fontSize = 16.sp)
)
// Theme.kt
@Composable
fun AppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) { /* 如上 */ }
小结
MaterialTheme 管理颜色、字体、形状三要素。用语义化颜色角色(primary/onPrimary/surface)而非硬编码颜色,暗色主题自动适配。Android 12+ 开启动态颜色融入系统壁纸。主题统一管理,改一处全局生效。下一节学习动画。