Material3 组件库:从 AppCompat 到现代 Material Design
说实话,Android 的 UI 框架演进,我一直觉得挺有意思的。从早期的 Holo 风格,到 Material Design 1.0,再到现在的 Material 3(简称 M3),每一次迭代都在解决实际问题。今天我们就来聊聊 Material3 组件库,以及它带来的那些新玩意儿。
我个人习惯把 Material3 看作是 Google 对「设计系统」的一次彻底重构。它不再只是换个颜色、改个圆角那么简单。M3 引入了动态颜色、新的组件规范,还有对自适应布局的深度支持。说白了,它想让你的 App 在不同设备上看起来都像「亲儿子」。
从 AppCompat 到 Material3:迁移路径
很多老项目还在用 AppCompat 主题。这没问题,AppCompat 依然稳定。但如果你想用上 M3 的新特性,比如动态颜色、SearchBar、BottomSheet 这些,就得迁移到 Material3。
迁移其实不复杂。你只需要做两件事:
- 把主题的 parent 从
Theme.MaterialComponents.DayNight改成Theme.Material3.DayNight - 引入 M3 的依赖库
// build.gradle (app)
implementation 'com.google.android.material:material:1.12.0'
嗯,这里要注意。M3 的依赖库版本至少要到 1.9.0 以上,才能获得完整的动态颜色支持。我建议直接用 1.12.0,稳定且 bug 少。
shapeAppearance 属性没适配。
主题切换与动态颜色:让 App 学会「看」壁纸
动态颜色是 M3 最让我兴奋的特性。它可以从用户的壁纸中提取主色、次色和中性色,然后自动生成一套完整的配色方案。你的 App 不需要写死颜色,系统帮你搞定。
实现起来很简单:
<!-- themes.xml -->
<style name="Theme.MyApp" parent="Theme.Material3.DayNight.NoActionBar">
<item name="colorPrimary">@color/m3_dynamic_primary</item>
<item name="colorSecondary">@color/m3_dynamic_secondary</item>
<item name="colorTertiary">@color/m3_dynamic_tertiary</item>
</style>
然后在代码里,你不需要做任何额外处理。系统会自动读取壁纸颜色并应用到组件上。但有个前提:用户必须开启「动态颜色」开关(Android 12+)。
DynamicColors.getColor(context, R.attr.colorPrimary)。我一般在自定义 View 里用这个,确保颜色和系统一致。
主题切换呢?M3 支持亮色/暗色主题自动切换。你只需要在 res/values-night 目录下放一份暗色主题的配置即可。系统会根据系统设置自动切换。
但如果你想要手动切换(比如 App 内设置),可以用 AppCompatDelegate.setDefaultNightMode()。我个人习惯把这个逻辑封装在 BaseActivity 里,这样所有页面统一管理。
TopAppBar 与 NavigationBar:适配 M3 新规范
TopAppBar 在 M3 里变化挺大的。它不再只是一个简单的标题栏,而是变成了一个可折叠、可交互的容器。M3 的 TopAppBar 有三种模式:
- Small:和以前一样,显示标题和操作按钮
- Medium:标题更大,适合作为页面主标题
- Large:标题超大,配合滚动可以折叠成 Small
我个人最喜欢 Large 模式。它让页面看起来更有层次感。实现起来也不复杂:
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="我的页面"
app:titleCentered="false" />
如果你想要 Large 模式,需要配合 CollapsingToolbarLayout 使用。嗯,这里有个坑:Large 模式的标题默认是居左的,如果你想要居中,得自己写布局。我建议不要强行居中,M3 的设计规范就是居左,强行改反而奇怪。
NavigationBar 呢?M3 的 NavigationBar 就是以前的 BottomNavigationView。它现在支持三个或五个标签,而且有「活动指示器」动画。说白了,就是选中项会有一个小圆点或者高亮条。
适配很简单:
<com.google.android.material.navigation.NavigationBarView
android:id="@+id/nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:menu="@menu/bottom_nav_menu" />
但要注意,M3 的 NavigationBar 默认高度比之前高了 8dp。如果你之前有自定义间距,可能需要重新调整。
Material3 中的新组件:SearchBar 与 BottomSheet
M3 引入了一些全新的组件,其中 SearchBar 和 BottomSheet 是我觉得最实用的。
SearchBar:搜索体验的现代化改造
SearchBar 不是一个简单的 EditText。它是一个可展开的搜索入口,点击后会弹出一个全屏的搜索界面(SearchView)。它支持语音输入、历史记录、搜索建议等。
用法:
<com.google.android.material.search.SearchBar
android:id="@+id/search_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="搜索..."
app:menu="@menu/search_menu" />
然后在代码里,你需要把它和 SearchView 关联起来:
val searchBar = findViewById<SearchBar>(R.id.search_bar)
val searchView = findViewById<SearchView>(R.id.search_view)
searchBar.setOnClickListener {
searchView.show()
}
searchView.addTransitionListener { _, _, state ->
if (state == SearchView.TransitionState.SHOWN) {
// 搜索界面已展开
}
}
我曾经在一个电商项目里用 SearchBar 替换了原来的 EditText。用户体验提升很明显——搜索界面自带过渡动画,而且支持语音输入,用户反馈很好。
BottomSheet:更灵活的底部弹窗
M3 的 BottomSheet 有两种:Modal BottomSheet(模态)和 Persistent BottomSheet(持久)。Modal 是弹窗,需要用户主动关闭;Persistent 是固定在页面底部的面板,可以上下拖动。
Modal BottomSheet 的用法:
val bottomSheet = ModalBottomSheet(context)
val view = layoutInflater.inflate(R.layout.sheet_content, null)
bottomSheet.setContentView(view)
bottomSheet.show()
Persistent BottomSheet 则需要配合 CoordinatorLayout 使用:
<androidx.coordinatorlayout.widget.CoordinatorLayout ...>
<com.google.android.material.bottomsheet.BottomSheetBehavior
android:id="@+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="200dp"
app:behavior_peekHeight="80dp"
app:behavior_hideable="true" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
嗯,这里有个坑。Persistent BottomSheet 的 peekHeight 决定了它默认显示的高度。如果你设置得太小,用户可能看不到内容。我建议至少 80dp,配合一个明显的拖拽手柄。
知识体系总览
为了让你更直观地理解 M3 组件库的结构,我画了一张图:
总结一下
Material3 不是简单的 UI 升级。它带来了动态颜色、新的组件规范,还有对自适应布局的深度支持。如果你还在用 AppCompat,我建议你尽快迁移。迁移成本不高,但用户体验的提升是实实在在的。
最后说一句:不要为了用 M3 而用 M3。如果你的 App 用户群体还在 Android 10 以下,动态颜色就用不了。这时候你可以考虑降级方案——用 M3 的组件,但颜色自己定义。灵活一点,总没错。
- 迁移到 M3 只需改主题 parent 和依赖版本
- 动态颜色自动适配壁纸,但需要 Android 12+
- TopAppBar 支持三种模式,Large 模式需要 CollapsingToolbarLayout
- SearchBar 和 BottomSheet 是 M3 的亮点,值得优先使用
公众号:蓝海资料掘金营,微信deep3321