20、Material Design 3:Material You设计理念、主题与颜色系统、Material组件(BottomNavigation、TopAppBar、Card)、动态颜色适配
好,咱们今天聊点真正让Android应用“活起来”的东西——Material Design 3,也就是大家常说的Material You。
说实话,从Material Design 1.0到2.0,Google一直在打磨设计语言。但到了3.0,我觉得它才真正找到了灵魂。为什么?因为它不再是一套死板的规范,而是一套能“感知”用户个性的系统。
20.1 Material You:从“千人一面”到“千人千面”
Material You的核心思想,说白了就是:你的手机,应该像你。
你想想看,以前我们做App,主题色是固定的。老板说用蓝色,全公司App就都是蓝色。用户拿到手里,跟隔壁张三的App一模一样。这合理吗?
Material You打破了这种僵局。它会从用户的壁纸中提取主色调,然后自动生成一套完整的配色方案。你的App,会随着用户壁纸的变化而自动换装。
我在项目中遇到过最典型的场景:用户反馈说“为什么我的App颜色跟别人不一样?”——这在以前是Bug,在Material You时代,这是Feature。
- 个性化:颜色来自用户壁纸,每个人都是独一无二的
- 自适应:组件、布局、动效都围绕颜色系统展开
- 无障碍:颜色对比度、字体大小都经过优化,天生友好
20.2 主题与颜色系统:别再用ColorPrimary了
如果你还在用colorPrimary、colorAccent那套老写法,我建议你趁早改。Material You引入了一套全新的颜色系统,叫动态颜色。
这套系统把颜色分成了五类角色:
| 颜色角色 | 作用 | 我常用的场景 |
|---|---|---|
| Primary | 主色,用于核心组件 | TopAppBar背景、FAB按钮 |
| On Primary | 主色上的文字/图标色 | TopAppBar上的标题文字 |
| Secondary | 辅助色,用于次要组件 | 底部导航栏选中状态 |
| Surface | 表面色,用于卡片、背景 | Card的背景、Dialog背景 |
| Error | 错误色,用于提示 | 输入框校验失败时的边框 |
嗯,这里要注意:不要手动硬编码这些颜色。你应该通过主题属性来引用它们,比如?attr/colorPrimary。这样当用户壁纸变了,颜色会自动跟着变。
我曾经踩过一个坑:在自定义View里直接写了Color.BLUE,结果动态颜色一开,那个View死活不变色。后来改成ContextCompat.getColor(context, R.attr.colorPrimary)才搞定。
20.3 核心组件实战:BottomNavigation、TopAppBar、Card
光说不练假把式。咱们直接看代码,看看Material You组件怎么用。
20.3.1 BottomNavigation:底部导航栏
底部导航栏是App的“骨架”,用户靠它切换主要页面。Material 3的BottomNavigation支持动态颜色,选中项会自动使用colorPrimary。
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_nav_menu"
app:itemIconTint="@color/bottom_nav_color"
app:itemTextColor="@color/bottom_nav_color"
app:labelVisibilityMode="labeled" />
注意那个@color/bottom_nav_color,它应该是一个selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="?attr/colorPrimary" />
<item android:color="?attr/colorOnSurfaceVariant" />
</selector>
这样选中时自动用主色,未选中时用浅色。用户换壁纸,颜色自动变。
20.3.2 TopAppBar:顶部应用栏
TopAppBar在Material 3里有了新变化。它支持大标题模式和紧凑模式,滚动时还能自动切换。
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/top_app_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:title="我的应用"
app:titleTextColor="?attr/colorOnPrimary"
app:navigationIcon="@drawable/ic_menu" />
我个人习惯把TopAppBar和CollapsingToolbarLayout配合使用,实现那种“图片折叠+标题浮现”的效果。但要注意:CollapsingToolbarLayout在Material 3里需要额外配置,否则动态颜色可能不生效。
20.3.3 Card:卡片组件
Card是Material Design的标志性组件。Material 3的Card默认带圆角和阴影,而且支持填充色和轮廓色两种风格。
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:cardBackgroundColor="?attr/colorSurface"
app:strokeColor="?attr/colorOutline"
app:strokeWidth="1dp"
app:cardCornerRadius="12dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="这是一张卡片"
android:textColor="?attr/colorOnSurface" />
</com.google.android.material.card.MaterialCardView>
这里有个小技巧:app:strokeColor设置为?attr/colorOutline,卡片会有一个淡淡的边框,视觉上更精致。如果去掉stroke,就是纯填充色卡片,适合内容较多的场景。
20.4 动态颜色适配:让App“读懂”用户壁纸
动态颜色是Material You的杀手锏。但实现起来并不复杂,核心就两步:
- 在主题中启用动态颜色
- 使用动态颜色属性
首先,在themes.xml中,把父主题改成Material 3的动态颜色主题:
<style name="Theme.MyApp" parent="Theme.Material3.DynamicColors.DayNight">
<!-- 不需要手动定义颜色,系统会自动从壁纸提取 -->
</style>
然后,在布局和代码中,全部使用?attr/colorPrimary、?attr/colorSurface这类属性。系统会自动映射到从壁纸提取的颜色上。
如果你需要手动获取动态颜色,可以用这个工具类:
val colors = DynamicColors.getColorScheme(context)
val primaryColor = colors.primary
val surfaceColor = colors.surface
我曾经在适配动态颜色时遇到一个问题:某些国产手机不支持动态颜色。嗯,这确实是个坑。解决方案是:先检测是否支持,如果不支持,就回退到预设的配色方案。
if (DynamicColors.isDynamicColorAvailable()) {
DynamicColors.applyToActivityIfAvailable(activity)
} else {
// 使用预设的Material 3颜色
activity.setTheme(R.style.Theme_MyApp_Fallback)
}
- 动态颜色只在Android 12+上原生支持。低版本可以通过Material库的兼容层实现,但效果可能略有差异。
- 不要在所有地方都用动态颜色。比如错误提示、警告信息,建议用固定颜色,确保用户能识别。
- 测试时记得换不同的壁纸,看看颜色变化是否合理。有些壁纸提取出来的颜色可能对比度不够。
20.5 知识体系总览
为了帮你理清思路,我画了一张结构图。它展示了Material You从设计理念到具体实现的完整链路。
好了,关于Material Design 3的核心内容就这些。记住:设计规范是死的,用户是活的。Material You给了你一套强大的工具,但怎么用、用多少,最终还是取决于你对用户的理解。
公众号:蓝海资料掘金营,微信deep3321