1. 准备工作
在此 Codelab 中,您将更新起始应用(小费计算器应用),以使用 Material Design 3 中的新功能,从而根据用户的壁纸为应用的界面动态设置主题。以下是应用了动态配色的应用的几张屏幕截图。您还将了解其他一些可让您控制颜色应用方式的场景。
前提条件
开发者应
- 熟悉 Android 中的基本主题概念
- 擅长修改应用主题
学习内容
- 如何区分现有的 Material 组件和 Material 3 主题
- 如何将主题更新为 Material 3
- 如何使用我们的工具创建主题并应用这些主题
- 主题属性之间的关系
所需条件
- 一台安装了 Android Studio 的计算机。
- Tip Time 应用的代码。https://github.com/google-developer-training/android-basics-kotlin-tip-calculator-app-solution
2. 起始应用概览
Tip Time 应用是一款小费计算器应用,提供自定义小费的选项。它是我们的《使用 Kotlin 进行 Android 开发的基础知识》培训课程中的示例应用之一。
3. 更新 Gradle 依赖项
在我们更新实际主题并应用动态配色之前,您需要在应用的 build.gradle 文件中进行一些更改。
在“dependencies”部分,确保 Material 库为 1.5.0-alpha04 或更高版本:
dependencies {
// ...
implementation 'com.google.android.material:material:<version>'
}
在 android 部分,更改 compileSdkVersion 和 targetSdkVersion
到 31 或更高版本:
android {
compileSdkVersion 31
// ...
defaultConfig {
// ...
targetSdkVersion 31
}
}
这些说明假定应用具有相对较新的依赖项。对于尚未使用 Material 或更低版本的应用,请查看适用于 Android 的 Material Design 组件的使用入门文档中的说明。
无论您在何处创建主题,请将对 Theme.MaterialComponents.*
的引用更改为 Theme.Material3.*
。某些样式在 Material3 命名空间中还没有新样式,但当父主题更新为 Theme.Material3.*
后,大多数组件仍会继承新样式。我们可以看到,按钮现在采用了新的圆角主题。
在下面的主题文件中,唯一发生变化的是父主题。我们稍后会完全替换此主题。一些颜色属性已作废,我们创建的一些自定义样式现在是 Material3 中的标准样式,但我们希望您将
themes.xml
<style name="Theme.TipTime" parent="Theme.Material3.Light">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/green</item>
<item name="colorPrimaryVariant">@color/green_dark</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/blue</item>
<item name="colorSecondaryVariant">@color/blue_dark</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- For text input fields -->
<item name="textInputStyle">@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox</item>
<!-- For radio buttons -->
<item name="radioButtonStyle">@style/Widget.TipTime.CompoundButton.RadioButton</item>
<!-- For switches -->
<item name="switchStyle">@style/Widget.TipTime.CompoundButton.Switch</item>
</style>
4. 了解颜色主题和颜色角色
Material 3 颜色系统以组织有序的方式将颜色应用到界面。Theme.AppCompat
中的许多属性仍在使用。不过,我们在 Theme.MaterialComponents.*
中添加了更多的属性,在 Theme.Material3.*
中添加了更多的属性,因此请务必检查应用的所有屏幕,以确保没有从基本主题中渗漏未实现的属性。
了解颜色角色
Material 3 主题中有超过 20 个与颜色相关的属性。乍一看,这似乎有点让人望而生畏,但实际上会有几个关键的颜色与 4-5 种相同的颜色角色相结合,从而形成衍生颜色。
这些颜色组包括:
- Primary(主色),即应用的主色
- secondary,应用的次要颜色
- 第三色,用于辅助主色和辅色的第三种颜色
- 错误,用于错误文本和对话框
- 背景
- Surface、SurfaceVariant、Surface Inverse
主要、次要、第三和错误角色如下:
<基本颜色> | 基本颜色 |
on<基准颜色> | 在基本颜色上显示的图标和文本的颜色 |
<base color>容器 | 派生自基础颜色、颜色,用于按钮、对话框等 |
on<base color>容器 | 容器中图标和文字的颜色 |
例如,Material 3 中采用默认样式的悬浮操作按钮使用 Primary
作为其基本颜色,因此它使用 primaryContainer
作为按钮的背景颜色,使用 onPrimaryContainer
作为其内容。
手动自定义主题时,您至少应验证您更改的每个基础颜色的 on<base color>
属性是否仍然清晰易读。
最佳实践是同时调整一个颜色组中的所有角色,以确保从基础到您的应用没有任何伪影。
背景和 Surface 基础颜色通常有两个角色:基础颜色本身和 on<base color>
(用于呈现在其上的图标或文本)。
5. 使用 Material Theme Builder 创建 Material 3 主题
借助 Material Theme Builder,您可以轻松构建自定义配色方案,使用其内置的代码导出功能迁移到 M3 颜色系统,并充分利用动态配色功能。了解详情 material.io/material-theme-builder
Tip Time 应用主题包含多种组件样式,但大多数样式都是 Material 3 主题中的默认样式。我们只需要关注两个主要颜色,即主要颜色和次要颜色。
这分别对应于绿色主要颜色 (#1B5E20) 和蓝色次要颜色 (#0288D1)。
您可以将这些颜色输入到 Material 主题构建器中,并导出完整的主题(假设在其他地方提供指向完整概览的链接)。
请注意,您输入的颜色可能会改变色调,以符合颜色生成算法,并确保颜色互补且易读。
以下是您输入自定义颜色时生成的值的子集。
6. 使用 Material Theme Builder 导出文件
导出归档包含 values 和 values-night/ 目录,它们都有自己的 topics.xml 文件,分别对应于浅色和深色主题。所有颜色均在 values/colors.xml 中定义。
这些文件可以按原样复制,但您必须更改主题名称 AndroidManifest.xml 或主题文件,以便相互匹配。工具的默认名称是 AppTheme。
重启应用,它看起来几乎完全一样。一个值得注意的变化是 Switch 和 RadioButtons,它们的选定状态现在以主要颜色与次要颜色的色调为主题。在较大的应用中,您可能需要重新访问某些设计。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tiptime">
<application ...>
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
7. 正在添加动态配色
使用适当的 Material 3 主题后,我们可以通过添加一些小小的新增内容使界面变得动态。
借助 Dynamic Colors API,您可以将动态配色应用于所有 Activity
应用内、单个 activity 或单个 View 或 fragment 中。适用于
这个应用,我们将全局应用动态配色。
创建应用类文件
class TipTimeApplication: Application() {
override fun onCreate() {
// Apply dynamic color
DynamicColors.applyToActivitiesIfAvailable(this)
}
}
我们需要在 Android 清单中引用以下新创建的文件:
AndroidManifest.xml
< application android name=".TipTimeApplication
<!--- Other existing attributes –>
</application >
在 Android 12 及更高版本的系统中,系统会检查用户默认方案的壁纸)以生成多个色调调色板。这些调色板中的值用于创建 ThemeOverlay
。
DynamicColors 类会注册一个在 ActivityPreCreated
上截获的 ActivityLifecycleCallbacks
,以应用系统创建的动态主题叠加层或您提供的动态主题叠加层。
8. 应用自定义主题叠加层
我们的工具可以导出主题叠加层,但是,如果您要覆盖少量属性,也可以手动创建它们。
主题叠加层旨在与另一个主题结合使用,并且仅提供在基本主题之上更改的值。
我们假设出于某种原因(比如品牌推广),我们需要主色调为红色阴影。我们可以使用以下文件和属性来完成此操作。
colors.xml
<resources>
<color name="overlay_light_primary">#9C4146</color>
<color name="overlay_light_onPrimary">#FFFFFF</color>
<color name= "overlay_light_primaryContainer">#FFDADB</color>
<color name="overlay_light_onPrimaryContainer">#400008</color>
</resources >
themes_overlays.xml
<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.Light">
<item name="colorPrimary">@color/overlay_light_primary</item>
<item name="colorOnPrimary">@color/overlay_light_onPrimary</item>
<item name="colorPrimaryContainer">@color/overlay_light_primaryContainer</item>
<item name="colorOnPrimaryContainer">@color/overlay_light_onPrimaryContainer<item>
</style>
对于上述代码,Android 12 会应用动态浅色主题,并将您的更改叠加到该主题之上。或者,您也可以使用任何有效的 ThemeOverlay 作为父项,包括以下任意一项:
ThemeOverlay.Material3.Light
ThemeOverlay.Material3.Dark
ThemeOverlay.Material3.DayNight ThemeOverlay.Material3.DynamicColors.Dark
ThemeOverlay.Material3.DynamicColors.DayNight
如需使用此主题叠加层而不是 Material 默认值,请将对 DynamicColors.applyToActivitiesIfAvailable
的调用更改为:
DynamicColors.applyToActivitiesIfAvailable(this, R.style.AppTheme_Overlay)
9. 向自定义属性添加动态配色
到目前为止,我们已经替换了 Material 3 主题中已存在的属性。还有一种可能是动态配色的情况,那就是我们可能需要分配一个或多个自定义属性。
应用选择启用动态配色后,可以使用 5 种色调调色板 - 3 种强调色和 2 种中性调色板,它们具有以下近似角色:
system_accent1 | 原色色调 |
system_accent2 | 次要色调 |
system_accent3 | 三级色调 |
system_neutral1 | 中性背景和表面 |
system_neutral2 | 中性表面和轮廓 |
每个调色板都有许多色调步骤,如白色
设置为黑色:0、10、50、100、200、300、400、500、600、700、800、900、1000。
在为动态配色设计界面时,您应该少考虑具体颜色,而应多考虑该组件的色调和亮度与设计系统中其他组件的关系。
假设您希望使用辅助强调色调色板为图标设置主题,并且您通过 attrs.xml 中的以下条目为图标着色添加了一个属性。
attrs.xml
<resources>
<attr name="iconColor" format="color" />
</resources>
您的主题叠加层可能如下所示:
<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.DayNight">
<item name="iconColor">@android:color/system_accent2_600</item>
</style>
当您重新安装应用并更换壁纸时,该应用会沿用以下辅助调色板。
这些调色板特定于 Android 12 (API 31),因此您需要将相关文件放在带有 -v31
后缀的文件夹中,除非应用的最低 SDK 设置为 31 或更高版本。
10. 总结
在此 Codelab 中,您已学到以下知识:
- 添加依赖项以将主题升级到 Material 3。
- 了解新的颜色组和角色。
- 了解如何从静态主题迁移到动态配色。
- 了解如何使用主题叠加层以及为自定义主题属性使用动态配色。