更改应用主题

1. 准备工作

Material 是 Google 打造的设计系统,旨在帮助开发者针对 Android 和其他平台打造优质的数字体验。完整的 Material 系统包括关于应用视觉、动作和互动设计的设计指南,但此 Codelab 将重点介绍如何更改 Android 应用的色彩主题。

此 Codelab 使用 Empty Activity 应用模板,但您可以使用您正在开发的任何 Android 应用。如果您是在“Android 基础知识”课程中学习此 Codelab,就可以使用 Tip Time 应用。

前提条件

  • 知道如何在 Android Studio 中通过模板创建 Android 应用。
  • 知道如何在模拟器或设备上通过 Android Studio 运行 Android 应用。
  • 运行 API 28 (Android 9) 或 API 29 (Android 10) 或更高版本的 Android 设备或模拟器。
  • 知道如何修改 XML 文件。

学习内容

  • 如何根据 Material Design 原则为您的应用选择有效颜色
  • 如何将颜色设置为应用主题的一部分
  • 一种颜色的 RGB 分量
  • 如何向 View 应用样式
  • 利用主题更改应用外观
  • 了解色彩对比度的重要性

所需条件

  • 一台安装了最新的稳定版 Android Studio 的计算机
  • 用于访问 Material 颜色工具地网络浏览器和互联网连接

2. 设计和颜色

Material Design

Material Design 深受物质世界及其纹理(包括物体如何反射光和投射阴影)启发构建而成。它提供了一些准则,指导如何以具有可读性、吸引力和一致性的方式构建应用界面。借助 Material 主题设置,您可以依据关于自定义颜色、排版和形状的指南,针对应用调整 Material Design。Material Design 附带有内置基准主题,您可按原样使用这些主题。然后,您可以根据自己的喜好对其进行不同程度的自定义,使 Material 中的设计适合您的应用。

有关颜色的一些知识

无论是在现实世界还是在数字化领域,颜色无处不在。首先要知道的是,用户看到颜色的方式不尽相同,因此为应用选择颜色尤为重要,这有助于用户有效地使用您的应用。选择具有足够色彩对比度的颜色只是构建无障碍功能更出色的应用的一个环节。

55f93a1ea75d644a.png

颜色可以表示为 3 个十六进制数 #00-#FF (0-255),分别代表该颜色的红色、绿色和蓝色 (RGB) 分量。数字越大,该分量就越多。

e0349c33dd6fbafe.png

请注意,定义颜色时还可以添加一个 alpha 值 #00-#FF,它表示透明度(#00 = 0% = 完全透明,#FF = 100% = 完全不透明)。若添加 alpha 值,则该值为 4 个十六进制数 (ARGB) 中的第一个。如果未添加 alpha 值,系统会假定 #FF = 100%,即不透明。

然而,您无需自己生成这些十六进制数。系统提供了一些工具,可帮助您选择颜色,它们会为您生成这些数值。

您可能已在 Android 应用的 colors.xml 文件中看到了一些示例,其中包括 100% 黑色(R=#00、G=#00、B=#00)和 100% 白色(R=#FF, G=#FF、B=#FF):

<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>

3. 主题

样式可以指定 View 的属性,例如字体颜色、字号、背景颜色等。

主题是应用于整个应用、activity 或视图层次结构(而非仅仅单个 View)的样式集合。将某个主题应用于应用、activity、视图或视图组时,该主题将应用于相应元素及其所有子元素。主题还可以将样式应用于非视图元素,例如状态栏和窗口背景。

创建 Empty Activity 项目

如果您使用的是自己的应用,则可以跳过此部分。如果您需要一个应用以供使用,请按以下步骤创建 Empty Activity 应用。

  1. 打开 Android Studio。
  2. 使用 Empty Activity 模板创建一个新的 Kotlin 项目。
  3. 使用“TipTime”这一名称。如果您没有参加任何其他 Codelab,也可以选择保留默认名称“My Application”。
  4. 将最低 API 级别设为 19 (KitKat)。
  5. 在 Android Studio 创建完应用后,打开 activity_main.xml (app > res > layout > activity_main.xml)。
  6. 如有必要,请切换到 Code 视图。
  7. 使用以下 XML 代码替换所有文字:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="16dp"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:layout_gravity="center_horizontal"
        android:gravity="center_vertical"
        android:text="@string/primary_color"
        android:textAllCaps="true"
        android:textSize="12sp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="@string/button" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="8dp"
        android:gravity="center_vertical"
        android:text="@string/secondary_color"
        android:textAllCaps="true"
        android:textSize="12sp" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:contentDescription="@string/email_icon"
        app:srcCompat="@android:drawable/ic_dialog_email" />

</LinearLayout>
  1. 打开 strings.xml (app > res > values > strings.xml)。
  2. 使用以下 XML 代码替换所有文字:
<resources>
    <string name="app_name">TipTime</string>
    <string name="primary_color">Primary color</string>
    <string name="button">Button</string>
    <string name="secondary_color">Secondary color</string>
    <string name="email_icon">email icon</string>
</resources>
  1. 运行您的应用。该应用应如下面的屏幕截图所示。

8949c2a02d8fea15.png

该应用包含 TextViewButton,以便您了解您所选颜色在实际 Android 应用中显示的样子。在后续步骤中,我们会将按钮的颜色更改为主题的主色。

了解主题颜色

Android 应用界面的不同部分使用不同的颜色。为了帮助您在应用中合理使用颜色,并在整个过程中一致地使用这一颜色,主题系统会将这些颜色组合成与文本、图标等所用颜色相关的 12 个命名属性。您的主题不必指定所有这些颜色;您将选择主色和辅色,以及在这些颜色上绘制的文本和图标的颜色。

af6c8e0d93135130.png

“On”颜色用于在不同 surface 上绘制的文字和图标。

#

名称

主题属性

1

Primary

colorPrimary

2

Primary 变体

colorPrimaryVariant

3

Secondary

colorSecondary

4

Secondary 变体

colorSecondaryVariant

5

Background

colorBackground

6

Surface

colorSurface

7

Error

colorError

8

On Primary

colorOnPrimary

9

On Secondary

colorOnSecondary

10

On Background

colorOnBackground

11

On Surface

colorOnSurface

12

On Error

colorOnError

查看默认主题中定义的颜色。

  1. 在 Android Studio 中,打开 themes.xml (app > res > values > topics > topics.xml)。
  2. 请注意主题名称 Theme.TipTime,该名称以您的应用名称为基础。
<style name="Theme.TipTime" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
  1. 请注意,XML 行还指定了父主题 Theme.MaterialComponents.DayNight.DarkActionBar。其中,DayNight 是 Material Components 库中的预定义主题,DarkActionBar 表示操作栏使用深色。就像类从其父类继承属性一样,主题也会继承其父主题的属性。
  1. 查看文件中的项,另请注意,这些项的名称与上图中的名称类似:colorPrimarycolorSecondary 等。

themes.xml

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Theme.TipTime" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- Primary brand color. -->
        <item name="colorPrimary">@color/purple_500</item>
        <item name="colorPrimaryVariant">@color/purple_700</item>
        <item name="colorOnPrimary">@color/white</item>
        <!-- Secondary brand color. -->
        <item name="colorSecondary">@color/teal_200</item>
        <item name="colorSecondaryVariant">@color/teal_700</item>
        <item name="colorOnSecondary">@color/black</item>
        <!-- Status bar color. -->
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
        <!-- Customize your theme here. -->
    </style>
</resources>

并未定义所有色彩主题属性。未定义的颜色将继承其父主题的颜色。

  1. 另请注意,Android Studio 会在左侧边缘处绘制一个小的颜色样本。fe8f8c774074ca13.png
  2. 最后请注意,颜色被指定为颜色资源(例如 @color/purple_500),而不是直接使用 RGB 值。
  3. 打开 colors.xml (app > res > values > colors.xml),您将看到每种颜色资源的十六进制值。提醒您,前导 #FF 是 Alpha 值,表示颜色是 100% 不透明的。

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="purple_200">#FFBB86FC</color>
    <color name="purple_500">#FF6200EE</color>
    <color name="purple_700">#FF3700B3</color>
    <color name="teal_200">#FF03DAC5</color>
    <color name="teal_700">#FF018786</color>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>
</resources>

4. 选择应用主题颜色

至此您对主题属性已有所了解,现在可以选择一些颜色了!最简单的方法是使用 Color Tool(这是由 Material 团队提供的一款基于网络的应用)。此工具提供了预定义颜色的调色板,可以让您轻松查看不同界面元素使用这些颜色时的外观。

5f36ae5de34e0078.png

选择颜色

  1. 首先在 Primary 部分选择一个主色 (colorPrimary),例如 Green 900。颜色工具展示了该颜色在应用模型中的显示效果,同时还可以选择 LightDark 变体。310061c674eaefb9.png
  2. 点按 Secondary 部分,选择您喜欢的辅色(colorSecondary),例如 Light Blue 700。颜色工具展示了该颜色在应用模型中的显示效果,同样可以选择 LightDark 变体。
  3. 请注意,应用模型包括 6 个不同的模拟“屏幕”。点按模型上方的箭头,看看您在不同屏幕上所选颜色的显示效果。8260ceb61e8a8f2a.png
  4. 颜色工具还提供 Accessibility 标签页,让您了解自己的颜色在搭配黑色或白色文本时是否足够清晰。为了让应用具有更出色的无障碍功能,其中一个方面是要确保色彩对比度足够高:对于小文本,对比度为 4.5:1,而对于较大文本,对比度则为 3.0:1 或更高。详细了解色彩对比度329af13cbd2f6efb.png
  5. 对于 primaryColorVariantsecondaryColorVariant,您可以选择建议的浅色或深色变体。

为您的应用添加颜色

为颜色定义资源后,您可以更轻松地在应用的不同部分以一致的方式重复使用相同颜色。

  1. 在 Android Studio 中,打开 colors.xml (app > res > values > colors.xml)。
  2. 在现有颜色之后,使用上面选定的值 #1B5E20 定义名为 green 的颜色资源。
<color name="green">#1B5E20</color>
  1. 继续为其他颜色定义资源。其中大部分颜色都来自 Color Tool。请注意,green_lightblue_light 的值不同于该工具显示的内容;您将在后续步骤中使用它们。

green

#1B5E20

green_dark

#003300

green_light

#A5D6A7

blue

#0288D1

blue_dark

#005B9F

blue_light

#81D4FA

已针对黑白属性定义了颜色资源,因此您无需定义它们。

应用的 colors.xml 文件现在应如下所示:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="purple_200">#FFBB86FC</color>
    <color name="purple_500">#FF6200EE</color>
    <color name="purple_700">#FF3700B3</color>
    <color name="teal_200">#FF03DAC5</color>
    <color name="teal_700">#FF018786</color>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>

    <color name="green">#1B5E20</color>
    <color name="green_dark">#003300</color>
    <color name="green_light">#A5D6A7</color>
    <color name="blue">#0288D1</color>
    <color name="blue_dark">#005B9F</color>
    <color name="blue_light">#81D4FA</color>
</resources>

在主题中使用颜色

现在,您已为所选颜色命名,是时候在您的主题中使用这些颜色了。

  1. 打开 themes.xml (app > res > values > themes > themes.xml)。
  2. colorPrimary 更改为您选择的主色 @color/green
  3. colorPrimaryVariant 更改为 @color/green_dark
  4. colorSecondary 更改为 @color/blue
  5. colorSecondaryVariant 更改为 @color/blue_dark
  6. 确定 Text on PText on S 仍为白色 (#FFFFFF) 和黑色 (#000000)。如果您自行使用 Color Tool 并选择其他颜色,则您可能需要定义其他颜色资源。

完成后,主题应如下所示:

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Theme.TipTime" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- 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>
        <!-- Customize your theme here. -->
    </style>
</resources>
  1. 在模拟器或设备上运行您的应用,并看一下使用新主题时应用显示的样子。

3dba45374c1594e5.png

5. 深色主题

该应用模板包含默认的浅色主题,还包含深色主题变体。深色主题使用更暗、更柔和的颜色,并且:

  • 可以大幅减少耗电量(具体取决于设备的屏幕技术)。
  • 为弱视以及对强光敏感的用户提高可视性。
  • 让所有人都可以在光线较暗的环境中更轻松地使用设备。

为深色主题选择颜色

深色主题的颜色仍需要具有可读性。深色主题使用较深的界面颜色,且色彩强度有限。为了帮助确保可读性,其主要颜色通常与浅色主题的主要颜色相同,但饱和度更低。

为了提高深色主题的灵活性和易用性,我们建议在深色主题中使用较浅的色调 (200-50),而不要使用默认的色彩主题(饱和色调的范围为 900-500)。您之前选择了 green 200 和 light blue 200 作为浅色。对于您的应用,您需使用浅色作为主色,并将主色用作变体。

更新主题的深色版本

  1. 打开 themes.xml (night)Project 窗格中,选择 Android,然后依次前往 app > res > values > topics > topics.xml (night)
  1. colorPrimary 更改为所选主色的浅色变体 @color/green_light
  2. colorPrimaryVariant 更改为 @color/green
  3. colorSecondary 更改为 @color/blue_light
  4. colorSecondaryVariant 更改为 @color/blue_light。请注意,colorSecondaryVariant 的颜色可以与 colorSecondary 相同。

完成上述操作后,您的 themes.xml (night) 文件应如下所示:

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Application theme for dark theme. -->
    <style name="Theme.TipTime" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- Primary brand color. -->
        <item name="colorPrimary">@color/green_light</item>
        <item name="colorPrimaryVariant">@color/green</item>
        <item name="colorOnPrimary">@color/black</item>
        <!-- Secondary brand color. -->
        <item name="colorSecondary">@color/blue_light</item>
        <item name="colorSecondaryVariant">@color/blue_light</item>
        <item name="colorOnSecondary">@color/black</item>
        <!-- Status bar color. -->
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
        <!-- Customize your theme here. -->
    </style>
</resources>
  1. 此时,系统不会使用 colors.xml 中定义的原始颜色(例如 purple_200),因此您可以将其删除。

试用深色主题

您可以在设备上启用深色模式,看看您的主题在深色模式下呈现的效果。

对于 API 28 (Android 9)

  1. 再次运行应用。
  2. 切换到设置应用。
  3. 电池部分,找到省电模式

5f5098d8d63acfa9.png

  1. 立即开启

继续执行以下步骤。

对于 API 29 (Android 10) 或更高版本

  1. 再次运行应用。
  2. 切换到设置应用。
  3. 显示部分,找到深色主题开关。

6d9dc1ab3d19f8e6.png

  1. 启用深色主题,设备会切换到夜间模式。

75f134ecb7c1322a.png

对于任一 API

  1. 返回到您的应用,查看差异。

6cc918d7c3613539.png

最明显的变化是深色背景配浅色文本,而不是浅色背景配深色文本。此外,深色主题中的按钮颜色也不如浅色主题中的鲜艳。

恭喜!您已成功创建了一个同时采用浅色主题和深色主题的新应用主题。

6. 解决方案代码

此 codelab 重点介绍如何定制主题的颜色,然而,主题还可以自定义文本、形状、按钮样式等许多属性。阅读此文章,了解自定义应用主题的其他方式!Android 样式设置:常见主题属性

此 Codelab 的解决方案代码如下所示。

colors.xml (app > res > values > colors.xml)

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>
    <color name="green">#1B5E20</color>
    <color name="green_dark">#003300</color>
    <color name="green_light">#A5D6A7</color>
    <color name="blue">#0288D1</color>
    <color name="blue_dark">#005B9F</color>
    <color name="blue_light">#81D4FA</color>
</resources>

values/themes.xml (app > res > values > themes > themes.xml)

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Theme.TipTime" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- 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>
        <!-- Customize your theme here. -->
    </style>
</resources>

values-night/themes.xml (app > res > values > themes > themes.xml (night))

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Application theme for dark theme. -->
    <style name="Theme.TipTime" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- Primary brand color. -->
        <item name="colorPrimary">@color/green_light</item>
        <item name="colorPrimaryVariant">@color/green</item>
        <item name="colorOnPrimary">@color/black</item>
        <!-- Secondary brand color. -->
        <item name="colorSecondary">@color/blue_light</item>
        <item name="colorSecondaryVariant">@color/blue_light</item>
        <item name="colorOnSecondary">@color/black</item>
        <!-- Status bar color. -->
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
        <!-- Customize your theme here. -->
    </style>
</resources>

7. 总结

  • 使用 Material Color Tool 选择应用主题的颜色。
  • 您也可以使用 Material palette 生成器来帮助选择调色板。
  • colors.xml 文件中声明颜色资源,以便更轻松地重复使用它们。
  • 深色主题可减少耗电量,并使您的应用在弱光环境下更易于阅读。

8. 了解更多内容