
Jetpack Compose Material 3 主题设置完全指南基于官方 Codelab 整理专为 Android 开发者打造一、什么是 Material 3 主题Material Design 3简称 M3是 Google 推出的最新设计系统用于创建美观、一致的数字化界面。Material 3 主题三大支柱┌─────────────────────────────────────────────────────────┐ │ Material 3 主题 │ ├─────────────────┬─────────────────┬─────────────────────┤ │ 配色方案 │ 排版系统 │ ⬜ 形状系统 │ │ ColorScheme │ Typography │ Shapes │ ├─────────────────┼─────────────────┼─────────────────────┤ │ 定义应用的颜色 │ 定义文字的样式 │ 定义组件的圆角 │ │ 浅色/深色主题 │ 字体大小/字重 │ 大小/形状 │ └─────────────────┴─────────────────┴─────────────────────┘二、配色方案ColorScheme2.1 五种关键颜色Material 3 配色方案基于5 种关键颜色生成颜色类型用途示例主色 (Primary)主要组件、显眼按钮、活动状态品牌色辅色 (Secondary)次要组件、过滤控件辅助品牌色第三色 (Tertiary)对比强调色、特殊场景装饰色中性色 (Neutral)背景、Surface灰度色错误色 (Error)错误状态、警告红色系2.2 颜色角色命名规则每个颜色都有对应的onXxx颜色用于在其上绘制内容// 主色系统primary// 主色背景onPrimary// 主色上的文字/图标颜色primaryContainer// 主色容器浅色调onPrimaryContainer// 容器上的文字颜色// 辅色系统secondary onSecondary secondaryContainer onSecondaryContainer// 第三色系统tertiary onTertiary tertiaryContainer onTertiaryContainer// 中性色系统background onBackground surface onSurface surfaceVariant onSurfaceVariant// 其他error,onError,errorContainer,onErrorContainer outline,outlineVariant2.3 生成配色方案推荐方式使用 Material 主题构建器打开主题构建器选择你的品牌主色如#825500自动生成完整的浅色/深色配色方案导出为 Jetpack Compose 代码2.4 代码实现Color.kt - 定义颜色值packagecom.example.reply.ui.themeimportandroidx.compose.ui.graphics.Color// 浅色主题颜色valmd_theme_light_primaryColor(0xFF825500)valmd_theme_light_onPrimaryColor(0xFFFFFFFF)valmd_theme_light_primaryContainerColor(0xFFFFDDB3)valmd_theme_light_onPrimaryContainerColor(0xFF291800)valmd_theme_light_secondaryColor(0xFF6F5B40)valmd_theme_light_onSecondaryColor(0xFFFFFFFF)valmd_theme_light_secondaryContainerColor(0xFFFBDEBC)valmd_theme_light_onSecondaryContainerColor(0xFF271904)valmd_theme_light_backgroundColor(0xFFFFFBFF)valmd_theme_light_onBackgroundColor(0xFF1F1B16)valmd_theme_light_surfaceColor(0xFFFFFBFF)valmd_theme_light_onSurfaceColor(0xFF1F1B16)// 深色主题颜色valmd_theme_dark_primaryColor(0xFFFFB951)valmd_theme_dark_onPrimaryColor(0xFF452B00)valmd_theme_dark_primaryContainerColor(0xFF633F00)valmd_theme_dark_onPrimaryContainerColor(0xFFFFDDB3)valmd_theme_dark_backgroundColor(0xFF1F1B16)valmd_theme_dark_onBackgroundColor(0xFFEAE1D9)valmd_theme_dark_surfaceColor(0xFF1F1B16)valmd_theme_dark_onSurfaceColor(0xFFEAE1D9)// 种子颜色用于生成主题valseedColor(0xFF825500)Theme.kt - 创建配色方案packagecom.example.reply.ui.themeimportandroidx.compose.foundation.isSystemInDarkThemeimportandroidx.compose.material3.MaterialThemeimportandroidx.compose.material3.lightColorSchemeimportandroidx.compose.material3.darkColorSchemeimportandroidx.compose.runtime.Composable// 浅色配色方案privatevalLightColorslightColorScheme(primarymd_theme_light_primary,onPrimarymd_theme_light_onPrimary,primaryContainermd_theme_light_primaryContainer,onPrimaryContainermd_theme_light_onPrimaryContainer,secondarymd_theme_light_secondary,onSecondarymd_theme_light_onSecondary,secondaryContainermd_theme_light_secondaryContainer,onSecondaryContainermd_theme_light_onSecondaryContainer,backgroundmd_theme_light_background,onBackgroundmd_theme_light_onBackground,surfacemd_theme_light_surface,onSurfacemd_theme_light_onSurface,// ... 其他颜色)// 深色配色方案privatevalDarkColorsdarkColorScheme(primarymd_theme_dark_primary,onPrimarymd_theme_dark_onPrimary,primaryContainermd_theme_dark_primaryContainer,onPrimaryContainermd_theme_dark_onPrimaryContainer,secondarymd_theme_dark_secondary,onSecondarymd_theme_dark_onSecondary,secondaryContainermd_theme_dark_secondaryContainer,onSecondaryContainermd_theme_dark_onSecondaryContainer,backgroundmd_theme_dark_background,onBackgroundmd_theme_dark_onBackground,surfacemd_theme_dark_surface,onSurfacemd_theme_dark_onSurface,// ... 其他颜色)// 主题可组合函数ComposablefunAppTheme(useDarkTheme:BooleanisSystemInDarkTheme(),content:Composable()-Unit){valcolorsif(!useDarkTheme){LightColors}else{DarkColors}MaterialTheme(colorSchemecolors,contentcontent)}2.5 应用主题到应用MainActivity.ktclassMainActivity:ComponentActivity(){overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContent{AppTheme{// 用主题包裹整个应用Surface(modifierModifier.fillMaxSize(),tonalElevation5.dp// 添加色调高度){ReplyApp()}}}}}预览配置Preview(uiModeConfiguration.UI_MODE_NIGHT_YES,nameDefaultPreviewDark)Preview(uiModeConfiguration.UI_MODE_NIGHT_NO,nameDefaultPreviewLight)ComposablefunReplyAppPreview(){AppTheme{ReplyApp()}}2.6 在组件中使用颜色ComposablefunMyComponent(){// 使用主题颜色Text(textHello,colorMaterialTheme.colorScheme.onSurface)Surface(colorMaterialTheme.colorScheme.primaryContainer){Text(Content)}// 添加色调高度Material 3 新特性Surface(tonalElevation4.dp,// 根据主色生成色调shadowElevation2.dp// 传统阴影){Content()}}三、排版系统Typography3.1 文本样式分类Material 3 将文本样式简化为5 个类别每个有大/中/小三种尺寸类别用途示例Display超大标题、数字显示Display Large/Medium/SmallHeadline章节标题Headline Large/Medium/SmallTitle组件标题、卡片标题Title Large/Medium/SmallBody正文内容Body Large/Medium/SmallLabel按钮文字、标签Label Large/Medium/Small3.2 默认字体比例Display Large → Roboto Regular 57/64 Display Medium → Roboto Regular 45/52 Display Small → Roboto Regular 36/44 Headline Large → Roboto Regular 32/40 Headline Medium → Roboto Regular 28/36 Headline Small → Roboto Regular 24/32 Title Large → Roboto Regular 22/28 Title Medium → Roboto Medium 16/24 Title Small → Roboto Medium 14/20 Body Large → Roboto Regular 16/24 Body Medium → Roboto Regular 14/20 Body Small → Roboto Regular 12/16 Label Large → Roboto Medium 14/20 Label Medium → Roboto Medium 12/16 Label Small → Roboto Medium 11/163.3 自定义排版Type.kt - 定义自定义字体packagecom.example.reply.ui.themeimportandroidx.compose.material3.Typographyimportandroidx.compose.ui.text.TextStyleimportandroidx.compose.ui.text.font.FontFamilyimportandroidx.compose.ui.text.font.FontWeightimportandroidx.compose.ui.unit.sp// 自定义字体可选valMyFontFamilyFontFamily.DefaultvalAppTypographyTypography(displayLargeTextStyle(fontFamilyMyFontFamily,fontWeightFontWeight.Normal,fontSize57.sp,lineHeight64.sp,letterSpacing(-0.25).sp),displayMediumTextStyle(fontFamilyMyFontFamily,fontWeightFontWeight.Normal,fontSize45.sp,lineHeight52.sp),headlineLargeTextStyle(fontFamilyMyFontFamily,fontWeightFontWeight.Normal,fontSize32.sp,lineHeight40.sp),titleLargeTextStyle(fontFamilyMyFontFamily,fontWeightFontWeight.Normal,fontSize22.sp,lineHeight28.sp),bodyLargeTextStyle(fontFamilyMyFontFamily,fontWeightFontWeight.Normal,fontSize16.sp,lineHeight24.sp),labelLargeTextStyle(fontFamilyMyFontFamily,fontWeightFontWeight.Medium,fontSize14.sp,lineHeight20.sp)// 其他样式使用默认值可以省略)3.4 在组件中使用排版ComposablefunMyTextComponent(){// 使用预定义的文本样式Text(text大标题,styleMaterialTheme.typography.headlineLarge)Text(text正文内容,styleMaterialTheme.typography.bodyLarge)Text(text按钮文字,styleMaterialTheme.typography.labelLarge)// 自定义样式基于主题样式修改Text(text强调文字,styleMaterialTheme.typography.bodyLarge.copy(fontWeightFontWeight.Bold,colorMaterialTheme.colorScheme.primary))}四、形状系统Shapes4.1 形状的作用形状定义组件的圆角大小影响视觉风格和品牌识别度。4.2 默认形状比例Material 3 提供多种形状尺寸用于不同组件形状类型用途默认值None无圆角0.dpExtraSmall极小圆角4.dpSmall小圆角8.dpMedium中等圆角12.dpLarge大圆角16.dpExtraLarge超大圆角28.dpFull全圆角胶囊形9999.dp4.3 自定义形状Shape.kt - 定义形状packagecom.example.reply.ui.themeimportandroidx.compose.foundation.shape.RoundedCornerShapeimportandroidx.compose.material3.Shapesimportandroidx.compose.ui.unit.dpvalAppShapesShapes(extraSmallRoundedCornerShape(4.dp),smallRoundedCornerShape(8.dp),mediumRoundedCornerShape(12.dp),largeRoundedCornerShape(16.dp),extraLargeRoundedCornerShape(28.dp))4.4 在组件中使用形状ComposablefunMyShapeComponent(){// 使用主题形状Surface(shapeMaterialTheme.shapes.small){Text(小圆角卡片)}Surface(shapeMaterialTheme.shapes.large){Text(大圆角卡片)}// 按钮默认使用全圆角Button(onClick{},shapeMaterialTheme.shapes.extraLarge){Text(按钮)}// 自定义形状Surface(shapeRoundedCornerShape(topStart16.dp,topEnd16.dp,bottomStart0.dp,bottomEnd0.dp)){Text(上圆角下方形)}}五、完整主题整合5.1 完整的 Theme.ktpackagecom.example.reply.ui.themeimportandroidx.compose.foundation.isSystemInDarkThemeimportandroidx.compose.material3.MaterialThemeimportandroidx.compose.material3.lightColorSchemeimportandroidx.compose.material3.darkColorSchemeimportandroidx.compose.runtime.ComposableComposablefunAppTheme(useDarkTheme:BooleanisSystemInDarkTheme(),content:Composable()-Unit){valcolorsif(!useDarkTheme){LightColors}else{DarkColors}MaterialTheme(colorSchemecolors,typographyAppTypography,shapesAppShapes,contentcontent)}5.2 项目结构app/ ├── src/main/java/com/example/reply/ │ └── ui/ │ ├── theme/ │ │ ├── Color.kt # 颜色定义 │ │ ├── Theme.kt # 主题整合 │ │ ├── Type.kt # 排版定义 │ │ └── Shape.kt # 形状定义 │ ├── components/ # 自定义组件 │ └── ... └── MainActivity.kt # 应用入口六、动态主题Dynamic Color6.1 什么是动态主题Android 12 支持动态取色根据用户壁纸自动生成主题颜色。6.2 实现动态主题ComposablefunAppTheme(useDarkTheme:BooleanisSystemInDarkTheme(),useDynamicColor:Booleantrue,// 是否启用动态颜色content:Composable()-Unit){valdynamicColorsif(useDynamicColorBuild.VERSION.SDK_INTBuild.VERSION_CODES.S){valcontextLocalContext.currentif(useDarkTheme){dynamicDarkColorScheme(context)}else{dynamicLightColorScheme(context)}}else{null}valcolorsdynamicColors?:if(!useDarkTheme){LightColors}else{DarkColors}MaterialTheme(colorSchemecolors,typographyAppTypography,shapesAppShapes,contentcontent)}七、深色主题支持7.1 自动跟随系统ComposablefunAppTheme(useDarkTheme:BooleanisSystemInDarkTheme(),// 自动跟随系统content:Composable()-Unit){// ...}7.2 手动切换主题ComposablefunSettingsScreen(){varuseDarkThemebyremember{mutableStateOf(false)}Switch(checkeduseDarkTheme,onCheckedChange{useDarkThemeit})AppTheme(useDarkThemeuseDarkTheme){// 应用内容}}八、最佳实践总结8.1 颜色使用原则✅ 正确做法❌ 错误做法使用MaterialTheme.colorScheme.xxx硬编码颜色值Color(0xFF...)使用onXxx颜色保证对比度在深色背景上用深色文字使用tonalElevation创建层次只用阴影不用色调8.2 排版使用原则✅ 正确做法❌ 错误做法使用预定义的typography.xxx每个 Text 都自定义 fontSize保持层次结构标题 正文 标签全文统一字号使用copy()修改现有样式从头创建 TextStyle8.3 形状使用原则✅ 正确做法❌ 错误做法统一圆角风格全用大圆角或小圆角混用不同圆角大小使用主题形状shapes.xxx每个组件都写 RoundedCornerShape按钮用大圆角卡片用中圆角所有组件用相同圆角九、快速参考表颜色角色速查// 主色系统MaterialTheme.colorScheme.primary MaterialTheme.colorScheme.onPrimary MaterialTheme.colorScheme.primaryContainer MaterialTheme.colorScheme.onPrimaryContainer// 背景/表面MaterialTheme.colorScheme.background MaterialTheme.colorScheme.surface MaterialTheme.colorScheme.surfaceVariant// 文字颜色MaterialTheme.colorScheme.onBackground MaterialTheme.colorScheme.onSurface MaterialTheme.colorScheme.onSurfaceVariant// 其他MaterialTheme.colorScheme.error MaterialTheme.colorScheme.outline排版样式速查// 显示MaterialTheme.typography.displayLarge MaterialTheme.typography.displayMedium MaterialTheme.typography.displaySmall// 标题MaterialTheme.typography.headlineLarge MaterialTheme.typography.headlineMedium MaterialTheme.typography.headlineSmall// 组件标题MaterialTheme.typography.titleLarge MaterialTheme.typography.titleMedium MaterialTheme.typography.titleSmall// 正文MaterialTheme.typography.bodyLarge MaterialTheme.typography.bodyMedium MaterialTheme.typography.bodySmall// 标签MaterialTheme.typography.labelLarge MaterialTheme.typography.labelMedium MaterialTheme.typography.labelSmall形状速查MaterialTheme.shapes.extraSmall// 4.dpMaterialTheme.shapes.small// 8.dpMaterialTheme.shapes.medium// 12.dpMaterialTheme.shapes.large// 16.dpMaterialTheme.shapes.extraLarge// 28.dp十、完整示例代码// MainActivity.ktclassMainActivity:ComponentActivity(){overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContent{AppTheme{Surface(modifierModifier.fillMaxSize(),tonalElevation5.dp){ReplyApp()}}}}}// 组件示例ComposablefunEmailListItem(email:Email){Surface(colorMaterialTheme.colorScheme.surface,shapeMaterialTheme.shapes.medium,modifierModifier.padding(horizontal16.dp,vertical8.dp)){Column(modifierModifier.padding(16.dp)){Text(textemail.sender,styleMaterialTheme.typography.titleMedium,colorMaterialTheme.colorScheme.onSurface)Text(textemail.subject,styleMaterialTheme.typography.bodyLarge,colorMaterialTheme.colorScheme.onSurfaceVariant)Text(textemail.preview,styleMaterialTheme.typography.bodySmall,colorMaterialTheme.colorScheme.outline)}}}参考资料Material 3 主题 CodelabMaterial Design 3 官方文档Material 主题构建器Compose 中的 Material Design 3