从 Android 12 开始,Material You 设计侧重于 Android 操作系统中的表现力和流动性,目标是帮助用户创建和拥有根据自身需求量身定制的单一、有凝聚力的体验。作为 Android 合作伙伴,我们鼓励您在 Android 设备中融入 Material You 设计,具体体现在以下方面:
- 动态颜色
- 动画效果
- 小部件
动态颜色
动态颜色是 Material You 设计的核心,也是 Android 多年战略的关键部分,旨在以其他设备无法实现的方式,为用户带来更简单、更深入的自定义功能。Material You 提供:
为用户和开发者提供一致且丰富的个性化故事,可在任何 Android 设备中使用。
让 Android OEM 有机会继续创新系统 UI 和第一方应用,使其与其硬件和品牌颜色、制造商和外形保持一致。
要充分利用动态颜色,请使用 Android 12 Material You 颜色提取方案,将其作为您向用户提供的软件的关键组成部分。在设备上,使用 AOSP 中的颜色提取逻辑,尤其是从单一壁纸或主题源颜色输入并通过 65 个颜色 API 输出的逻辑。有关动态颜色要求,请参阅使用动态颜色。
完整的动态颜色流程包括四个步骤,如下图所示:
图 1. Material You 动态颜色流程
用户通过 OEM 选择器更改壁纸或主题。
用户选择以下选项之一:
设备主题。 选择此选项后,Android 会自动选择符合要求的单一源颜色。
新壁纸 + 主题。 选择此选项后,AOSP 逻辑会自动从所选壁纸中选择单一源颜色。
AOSP 按照 AOSP 逻辑将单一源颜色扩展为 5 个色调调色板,每个调色板包含 13 种色调变体,然后填充 65 个颜色属性。
应用 UI 以在整个 Android 应用生态系统中保持一致的方式使用 65 个颜色属性。我们鼓励您为设备系统 UI 和 OEM 专用应用使用相同的调色板。
Android 12 补丁
要获取壁纸颜色提取的端到端逻辑,并使设备能够以与生态系统一致的方式填充 65 色 API,请在您的 Android 12 实现中加入以下补丁:
必需
强烈建议
在 ThemePicker 上指定自定义颜色
如果您使用的是 AOSP ThemePicker 应用,则当满足以下 两个 条件时,WallpaperPicker 应用会显示颜色部分
frameworks/base/packages/SystemUI/res/values/flags.xml
中的flag_monet
为true
。- 在
packages/apps/ThemePicker/res/values/override.xml
文件的themes_stub_package
中定义了带有包名称的系统桩 APK。
桩 APK 格式
此 APK 的示例版本可以在 packages/apps/ThemePicker/themes
中找到。
此 APK 应仅包含资源,详细说明可用的基本颜色及其名称。
桩应包含 res/xml
下的 XML 文件,格式如下
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="color_bundles">
<item>color1</item>
<item>color2</item>
<item>color3</item>
<item>color4</item>
</array>
<string name="bundle_name_color1">Blue</string>
<string name="bundle_name_color2">Red</string>
<string name="bundle_name_color3">Yellow</string>
<string name="bundle_name_color4">Green</string>
</resources>
在此文件中,color_bundles
中的每个 item
都有一个不同的名称,只要以下字符串被命名为 bundle_name_item
。
每个颜色都应有一个 bundle_name_item
字符串,其中包含每个颜色的描述性名称。可以通过将相应的翻译后的字符串添加到 res/values-language code
目录中来翻译这些名称。
实际的颜色值可以在同一个 XML 文件中,也可以在单独的资源 XML 文件中,格式如下
<resources>
<color name="color_primary_color1">#0000FF</color>
<color name="color_secondary_color1">#0000FF</color>
<color name="color_primary_color2">#ff0000</color>
<color name="color_secondary_color2">#ff0000</color>
<color name="color_primary_color3">#ffff00</color>
<color name="color_secondary_color3">#ffff00</color>
<color name="color_primary_color4">#00ff00</color>
<color name="color_secondary_color4">#00ff00</color>
</resources>
对于颜色包数组中的每个项目,都应该有一个 color_primary_item
和一个 color_secondary_item
条目(并且两种颜色应为相同的颜色)。这些 color
条目的值是基本颜色部分中显示的每种颜色的实际颜色代码。
步骤 1:构建用户主题体验
主题选择器是用户参与新的 Material You 个性化功能并可能在颜色选项或预设之间进行选择的地方。根据您的产品和用户群体,您可以通过使用主题选择器或壁纸选择器为用户提供更丰富的个性化和颜色体验。
- 当使用壁纸选择器时,默认情况下启用壁纸颜色提取。但是,您可以对选择器进行一些自定义,以便为用户提供更多选项。
步骤 2:将壁纸颜色提取到源颜色中
要启用壁纸颜色提取,请精选上面列出的 Android 12 补丁(此功能将在未来的 AOSP 版本中默认启用)。触发壁纸提取的 AOSP 逻辑从 frameworks/base/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
中的 ThemeOverlayController#mOnColorsChangedListener
开始,通过 WallpaperManager#onWallpaperColorsChanged
的方式。我们建议使用未修改的 AOSP 逻辑,以确保一致的开发体验。
默认情况下,该逻辑会选择最适合使用的最高频率颜色。要利用算法返回的其他源颜色并在主题选择器中将这些颜色呈现给用户,请使用 ColorScheme#getSeedColors(wallpaperColors: WallpaperColors)
。
为了适合使用,源颜色(无论是从壁纸提取还是用户选择的预设)必须具有至少 5 的 CAM16 色度值;这确保了源颜色在从单色转换为 65 种色调的颜色时不会受到细微暗色调的影响,并保持用户选择的代表性。要在 CAM16 中读取和修改颜色,请使用 Cam#fromInt
或 Cam#getInt
。
使用非动态调色板 对于不支持壁纸颜色提取的设备,您仍然可以通过执行以下操作来确保支持动态颜色的 Google 应用和第三方应用看起来很棒
- 通过禁用
frameworks/base/packages/SystemUI/res/values/flags.xml
中的flag_monet
来使用默认 Material 调色板。- 确保用户仍然可以使用预设主题选择器来个性化他们的操作系统。
步骤 3:将源颜色扩展为颜色 API
使用从上一步导出的单个源颜色,Android 生成 5 个独特的色调调色板(强调色 1-3,中性色 1-2),每个调色板包含 13 种颜色,每种颜色包含不同的亮度值(0 到 1000),总共 65 种颜色。Android 12 补丁 中提供的逻辑正确地实现了这种颜色扩展;下面提供的详细信息描述了实现方式。
为了开发人员的一致性,5 个色调调色板(accent1、accent2、accent3、neutral1、neutral2)及其对应的 13 种颜色必须基于具有以下 CAM16 色度和色相值更改的单个源颜色,如下所示
-
- 色度:使用“16”
- 色相:与源相同
-
- 色度:使用“32”
- 色相:正向旋转 60 度
-
- 色度:使用“4”
- 色相:与源相同
-
- 色度:使用“8”
- 色相:与源相同
CTS 包括用于验证亮度和色相 API 调用的测试。要运行,请使用 atest SystemPalette
。
步骤 4:在应用和 System UI 中使用动态颜色
在设备上设置动态颜色后,应用会遵循 Material 指南来使用这些颜色。Material 指南将于 2021 年 10 月 26 日在 material.io 上发布,供第三方应用采用。对于 System UI 和第一方应用,我们强烈建议在整个用户体验中集成动态颜色,使其与您的硬件和品牌相符,并帮助您区分您的设备。
有关一般动态颜色指南,请参阅以下内容
在应用和 System UI 中,对前景色元素使用强调色
@android:color/system_accent1_0 … 1000 // most-used foreground color group @android:color/system_accent2_0 … 1000 // alternate accent, used for surfaces @android:color/system_accent3_0 … 1000 // playful, analogous color
在应用和 System UI 中,对背景色元素使用中性色
@android:color/system_neutral1_0 … 1000 // most-used background color group @android:color/system_neutral2_0 … 1000 // used for higher-elevation surfaces
有关 Material You 如何映射颜色以及如何在 SysUI 中使用 API 的更多信息,请参阅其他资源。
步骤 5:在您的 AOSP WallpaperPicker 实现中添加动态颜色选项
为 Android 13 及更高版本构建
从 Android 13 开始,android.theme.customization.accent_color
已被弃用。添加了一个新的属性 android.theme.customization.theme_style
以支持不同的颜色变体。我们目前在代码库中有四种变体,如下所示
TONAL_SPOT = Default Material You theme since Android S.
VIBRANT = Theme where accent 2 and 3 are analogous to accent 1.
EXPRESSIVE = Highly chromatic theme.
SPRITZ = Desaturated theme, almost grayscale.
这些变体将发送到 Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES
,如下面的 JSON 所示
{
"android.theme.customization.system_palette":"B1611C",
"android.theme.customization.theme_style":"EXPRESSIVE"
}
为 Android 12 及更低版本构建
当使用自定义主题选择器时,设备必须通过提供以下格式的 JSON 文件(其中 746BC1
是有效的源颜色示例)将有效的源颜色发送到 Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES
{
"android.theme.customization.system_palette":"746BC1",
"android.theme.customization.accent_color":"746BC1"
}
这样做会跳过壁纸颜色提取(步骤 2),并直接将提供的源颜色扩展为 65 种颜色属性(步骤 3)。
步骤 6:提交工单
除了系统集成之外,您还需要提交工单并告知我们您的品牌名称 (Build.MANUFACTURER
)。由于大多数第三方应用都在使用 Material Components for Android 来显示动态颜色,因此我们正在使用硬编码的 允许列表来告知哪些设备集成了 动态颜色色调调色板 功能。
动画效果
流畅的运动使设备感觉现代和优质。为了建立和维护开发人员的信任和满意度,过度滚动和波纹是流畅运动的两个关键部分,需要看起来和感觉一致。
在您的操作系统中使用过度滚动
Android 12 在视图拉伸的形式中包含更灵敏、更动态的过度滚动运动,当用户尝试滚动超出列表边缘时显示。示例如下
图 2. Android 12 过度滚动效果,如设置中所示
为了开发人员的一致性,请确保您的设备上的整体过度滚动效果与以下效果相似
在
ActivityManager.isHighEndGfx()
返回 true 的设备上,过度滚动效果是屏幕的非线性拉伸(如上所示)。在性能较低的设备上,拉伸效果简化为线性拉伸(以减少系统负载)。
在第一方应用中使用过度滚动
当使用自定义视图时,您可能需要调整一些使用拉伸效果的应用和系统 UI。
要支持拉伸过度滚动,请升级到最新的库
RecyclerView
的androidx.recyclerview:recyclerview:1.3.0-alpha01
NestedScrollView
和EdgeEffectCompat
的androidx.core:core:1.7.0-alpha01
ViewPager
的androidx.viewpager:viewpager:1.1-alpha01
对于使用
EdgeEffect
的自定义布局,请考虑以下 UX 更改使用拉伸过度滚动时,用户不应在布局拉伸时与其内容进行交互。用户应仅操作拉伸本身,而不能例如按下内容中的按钮。
当用户在
EdgeEffect
动画发生时触摸内容时,他们应捕获动画并被允许操作拉伸。当前拉动值可从EdgeEffectCompat.getDistance()
获得。要操作拉动值并返回消耗的量,请使用
onPullDistance()
。这允许开发人员在手指将内容拉伸超出起始位置时,从拉伸平滑过渡到滚动。当使用嵌套滚动时,如果内容被拉伸,则拉伸应在嵌套内容之前消耗触摸动作,否则嵌套可能会在手指改变方向时滚动,而不是释放拉伸。
有关过度滚动的详细信息,请参阅动画滚动手势。
在您的操作系统中使用波纹(触摸反馈)
Android 12 包括更柔和、更微妙的触摸波纹,以便在点击按下时向用户提供反馈。
图 3. Android 12 波纹效果,具有更柔和的填充动画
为了开发人员的可预测性并提供出色的用户体验,请确保您的设备上的波纹效果与上面示例中显示的效果相似。虽然您无需执行任何特定的集成步骤来支持波纹效果,但您应该在您的设备上测试该效果,以检查您的实现中是否引入了任何意外的回归。
小部件
小部件是 Android 设备的关键组件。Android 12 包括所有 OEM 都应支持的新 API 和 API 功能。
在您的操作系统中,支持与小部件布局、大小和软件参数(例如,圆角大小)相关的开发人员 API。您的实现应正确支持小部件,通过 API 提供参数,并确保小部件可由用户调整大小和配置。
在您的应用中,尽可能利用新的 API 功能来更新或构建新的第一方小部件。对于您职权范围内的所有第一方应用小部件,请通读下面的开发者清单。
- 优先级基于平台的建议。
- 有关建议的详细信息,请点击“更改”列中的链接。
区域 更改 实施优先级 改善主屏幕体验 添加可缩放的预览 P1 添加小部件描述 P1 使小部件更易于个性化 P2(可选) 启用更平滑的过渡 P0 避免广播 trampoline P0 采用小部件指南 改进小部件大小和布局 P2 应用动态颜色 P0 实现圆角 P0 添加新的复合按钮 P2 简化现有小部件代码 简化 RemoteView Collections P2 简化 RemoteView 运行时 P2
其他资源
SysUI 颜色使用
(强调色 1 = A1,强调色 2 = A2,强调色 3 = A3,中性色 1 = N1,中性色 2 = N2)
图 4. System UI 中的动态颜色使用
Material 库颜色属性更新
Material 将在即将发布的版本中更新其主题属性,方法是创建用于为特定视图提供颜色的颜色角色。
颜色角色 | Android 主题属性 | 浅色主题 动态颜色 |
深色主题 动态颜色 |
---|---|---|---|
原色 | colorPrimary | system_accent1_600 | system_accent1_200 |
在原色之上 | colorOnPrimary | system_accent1_0 | system_accent1_800 |
辅助色 | colorSecondary | system_accent2_600 | system_accent2_200 |
在辅助色之上 | colorOnSecondary | system_accent2_0 | system_accent2_800 |
错误色 | colorError | N/A (red_600) | N/A (red_200) |
在错误色之上 | colorOnError | N/A (white) | N/A (red_900) |
背景色 | android:colorBackground | system_neutral1_10 | system_neutral1_900 |
在背景色之上 | colorOnBackground | system_neutral1_900 | system_neutral1_100 |
表面色 | colorSurface | system_neutral1_10 | system_neutral1_900 |
在表面色之上 | colorOnSurface | system_neutral1_900 | system_neutral1_100 |
Material 将使用以下指针更新其状态属性
颜色角色 | Android 主题属性 | 浅色主题 动态颜色 |
深色主题 动态颜色 |
---|---|---|---|
原色状态内容 | colorPrimaryStateContent | system_accent1_700 | system_accent1_200 |
原色状态层 | colorPrimaryStateLayer | system_accent1_600 | system_accent1_300 |
辅助色状态内容 | colorSecondaryStateContent | system_accent2_700 | system_accent2_200 |
辅助色状态层 | colorSecondaryStateLayer | system_accent2_600 | system_accent2_300 |
在原色状态内容之上 | colorOnPrimaryStateContent | system_accent1_0 | system_accent1_800 |
在原色状态层之上 | colorOnPrimaryStateLayer | system_accent1_900 | system_accent1_800 |
在辅助色状态内容之上 | colorOnSecondaryStateContent | system_accent2_0 | system_accent2_800 |
在辅助色状态层之上 | colorOnSecondaryStateLayer | system_accent2_900 | system_accent2_800 |
在原色容器状态内容之上 | colorOnPrimaryContainerStateContent | system_accent1_900 | system_accent1_900 |
在原色容器状态层之上 | colorOnPrimaryContainerStateLayer | system_accent1_900 | system_accent1_900 |
在辅助色容器状态内容之上 | colorOnSecondaryContainerStateContent | system_accent2_900 | system_accent2_900 |
在辅助色容器状态层之上 | colorOnSecondaryContainerStateLayer | system_accent2_900 | system_accent2_900 |
在三次色容器状态内容之上 | colorOnTertiaryContainerStateContent | system_accent3_900 | system_accent3_900 |
在三次色容器状态层之上 | colorOnTertiaryContainerStateLayer | system_accent3_900 | system_accent3_900 |
在表面色状态内容之上 | colorOnSurfaceStateContent | system_neutral1_900 | system_neutral1_100 |
在表面色状态层之上 | colorOnSurfaceStateLayer | system_neutral1_900 | system_neutral1_100 |
在表面变体状态内容之上 | colorOnSurfaceVariantStateContent | system_neutral2_700 | system_neutral2_200 |
在表面变体状态层之上 | colorOnSurfaceVariantStateLayer | system_neutral2_700 | system_neutral2_200 |
错误色状态内容 | colorErrorStateContent | red800 | red200 |
常见问题解答
颜色提取
用户更改壁纸后,颜色提取是自动完成还是需要从某处触发?
使用 Android 12 补丁后,壁纸颜色提取默认开启。
ThemeOverlayController.java
使用 ThemeOverlayController#mOnColorsChangedListener
和 WallpaperManager#onWallpaperColorsChanged
触发逻辑。
对于动态壁纸或视频壁纸,我们是否可以知道颜色提取何时从屏幕上取色?有些用户可能希望从最后一帧获取颜色,因为它显示的时间最长。
颜色提取在用户设置壁纸或屏幕电源循环后(响应 WallpaperEngine#notifyColorsChanged
)触发。最后一个 WallpaperColors
事件(来自动态壁纸)在用户关闭屏幕并重新打开屏幕后应用。
主题/壁纸选择器
如何启用主题选择器以显示多个源颜色供用户选择,而不是最高频率的颜色?有没有办法从提取逻辑中获取这些颜色?
有。在您的主题选择器中,您可以使用 ColorScheme#getSeedColors(wallpaperColors: WallpaperColors)
。
Pixel 上有一个名为主题图标的功能。它是否包含在您共享的三个补丁中?OEM 如何实现它?
否。主题图标处于 Beta 版,在 Android 12 中不可用。
有没有办法将 Google 壁纸应用与启用的颜色提取和选择功能一起使用?
有。可以通过按照本页前面描述的集成步骤在最新版本的 Google 壁纸应用中实现这些功能。
请联系您的 TAM 了解更多详情。
Google 能否分享应用或源代码,以便 OEM 可以在其设置菜单上实现自己的动态颜色预览版本,该版本看起来类似于 Google 壁纸选择器应用上显示的预览部分?
渲染预览的主要类是 WallpaperPicker2
和 Launcher3
。
壁纸预览屏幕是 WallpaperSectionController
。
如何在更改颜色后实现预览,如 Google 壁纸应用中所示?
壁纸选择器应用期望 Launcher 提供 ContentProvider
(基于 Launcher3
的启动器具有它)。预览由 Launcher 中的 GridCustomizationsProvider
提供,应在 Launcher 主 Activity 的 metadata 中引用,以便壁纸和样式应用可以读取它。所有这些都在 AOSP 的 Launcher3 中实现,OEM 可以使用。