66、主题与样式:Theme与Style定义、夜间模式、Material You动态颜色
说实话,主题和样式这块,是很多Android开发者容易忽略的“基本功”。
我刚入行那会儿,也觉得不就是改改颜色嘛,有什么好学的?直到接手一个老项目,里面光colors.xml就写了上千行,改个夜间模式要翻遍十几个布局文件……嗯,从那以后,我再也不敢小看Theme和Style了。
Style是什么?说白了就是“样式模板”
Style,就是一组属性的集合。你可以把它理解成一个“样式模板”。
比如你有一个按钮,想让它圆角、蓝色、文字白色。你当然可以在每个Button里写一遍。但更好的做法是——定义一个Style,然后到处引用。
<!-- res/values/styles.xml -->
<style name="PrimaryButton">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">48dp</item>
<item name="android:background">@drawable/btn_primary_bg</item>
<item name="android:textColor">@android:color/white</item>
<item name="android:textSize">16sp</item>
</style>
然后在布局里引用:
<Button
style="@style/PrimaryButton"
android:text="登录" />
你看,代码瞬间清爽了。而且后续要改样式,只需要改一个地方。
PrimaryButton、SecondaryButton、InputField。这样团队里谁都能一眼看懂。
Theme是什么?它是全局的“氛围”
Theme和Style很像,但作用范围不同。Theme作用于整个Activity或Application,它定义的是全局的“氛围”。
比如你希望整个App的主色调是蓝色,文字是深灰色,背景是浅灰色。这些就放在Theme里。
<!-- res/values/themes.xml -->
<style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="colorPrimary">@color/blue_500</item>
<item name="colorOnPrimary">@color/white</item>
<item name="colorSecondary">@color/teal_200</item>
<item name="android:colorBackground">@color/gray_50</item>
<item name="android:textColorPrimary">@color/gray_900</item>
</style>
然后在AndroidManifest.xml里引用:
<application
android:theme="@style/Theme.MyApp">
...
</application>
这样整个App就统一了。你想想看,如果每个页面都单独写颜色,那维护起来得多痛苦?
夜间模式:别让用户晚上“亮瞎眼”
夜间模式,说白了就是根据系统设置,自动切换一套暗色主题。
实现起来其实很简单:
- 在
res/values里定义日间主题 - 在
res/values-night里定义夜间主题 - 系统会自动根据时间或用户设置切换
举个例子,日间主题:
<!-- res/values/themes.xml -->
<style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="colorPrimary">@color/blue_500</item>
<item name="android:colorBackground">@color/white</item>
<item name="android:textColorPrimary">@color/black</item>
</style>
夜间主题:
<!-- res/values-night/themes.xml -->
<style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="colorPrimary">@color/blue_200</item>
<item name="android:colorBackground">@color/black</item>
<item name="android:textColorPrimary">@color/white</item>
</style>
Material You动态颜色:让App“随壁纸变色”
Material You是Android 12引入的新特性。它会从用户的壁纸中提取主色调,然后自动生成一套配色方案。
说白了,就是你的App颜色会跟着用户的壁纸走。每个人看到的App颜色都不一样。
启用方式很简单:
<!-- res/values/themes.xml -->
<style name="Theme.MyApp" parent="Theme.Material3.DynamicColors.DayNight">
...
</style>
然后在代码里调用:
// 在Application或Activity的onCreate中调用
DynamicColors.applyToActivityIfAvailable(this);
这样你的App就自动支持动态颜色了。你不需要手动定义任何颜色,系统会帮你搞定。
colors.xml里保留一套备用颜色。
知识体系总览
下面这张图,是我自己整理的主题与样式知识结构。你看一眼就能明白它们之间的关系:
实战建议:从零开始搭建主题系统
我个人习惯,在新项目一开始就搭好主题框架。具体步骤:
- 定义基础颜色:在
colors.xml里定义主色、辅色、背景色、文字色 - 定义Style:把常用的按钮、输入框、卡片都定义成Style
- 定义Theme:在
themes.xml里引用颜色,并设置全局属性 - 准备夜间模式:在
values-night里覆盖颜色值 - 启用Material You:在代码里调用
DynamicColors.applyToActivityIfAvailable()
这样一套下来,你的App就具备了完整的主题能力。后续加新页面,直接引用Style和Theme颜色就行,几乎不用再写重复代码。
@color/引用颜色,而不是硬编码。这样后期改主题色,只需要改colors.xml一个文件。
好了,关于主题与样式,我就讲这么多。记住一句话:好的主题系统,能让你的App看起来像是一个整体,而不是东拼西凑的碎片。
公众号:蓝海资料掘金营,微信deep3321