
深色主题适用于 Android 10(API 级别 29)及更高版本。它具有 具备以下优势:
- 会大幅减少耗电量,具体取决于设备的电量 屏幕技术
- 为弱视以及对强光敏感的用户提高可视性。
- 可让您在光线较暗的环境中更轻松地使用设备。
深色主题会应用于 Android 系统界面以及在设备上运行的应用。
在 Android 10 及更高版本中,您可以通过以下三种方式启用深色主题:
- 要使用系统设置,请依次转到设置 >展示广告 >Theme 启用深色主题。
- 使用“快捷设置”功能块,从通知栏中切换主题(启用后)。
- 在 Pixel 设备上,启用省电模式的同时也会启用深色主题。其他设备可能不支持此行为。
有关使用 WebView 组件对基于网络的内容应用深色主题的说明,请参阅使用 WebView 调暗网页内容的颜色。
在应用中支持深色主题
如需支持深色主题,请将应用的主题(通常可在 res/values/styles.xml
中找到)设置为继承 DayNight
主题:
<style name="AppTheme" parent="Theme.AppCompat.DayNight">
您还可以使用 Material Components 深色主题:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
这会将应用的主要主题与系统控制的夜间模式标记相关联, 在启用后,为应用提供默认的深色主题。
主题背景和样式
避免使用旨在于浅色主题背景下使用的硬编码颜色或图标。使用 主题属性或仅限夜间使用的资源
深色主题最重要的两个主题属性如下:
?android:attr/textColorPrimary
:一种通用文本颜色。时间是 在浅色主题下接近于黑色,在深色主题下接近于白色。它包含一个停用状态。?attr/colorControlNormal
:通用图标颜色。它包含一个停用状态。
我们建议使用Material Design
组件,因为它采用颜色主题设置
system,例如主题
属性 ?attr/colorSurface
和 ?attr/colorOnSurface
,可让您轻松访问
调整为合适的颜色。您可以在主题中自定义这些属性。
更改应用内主题
您可以允许用户在应用运行时更改其主题。建议的选项如下:
- 灯
- 深色
- 系统默认设置(推荐的默认选项)
这些选项直接映射到 AppCompat.DayNight
模式:
浅色:
MODE_NIGHT_NO
。深色:
MODE_NIGHT_YES
。系统默认设置:
MODE_NIGHT_FOLLOW_SYSTEM
。
如需切换主题,请执行以下操作:
对于 API 级别 31 及更高级别,请使用
UiModeManager#setApplicationNightMode
告知系统您的应用运行的是哪个主题。这样,系统就可以 在启动画面期间显示主题在 API 级别 30 及更低级别中,请使用
AppCompatDelegate.setDefaultNightMode()
来切换主题。
Force Dark
Android 10 提供了 Force Dark 功能,让开发者能够
快速实现深色主题,而无需明确设置 DayNight
主题。
Force Dark 会分析您采用浅色主题的应用的各个视图,并在相应视图在屏幕上显示之前,自动应用深色主题。您可以搭配使用 Force Dark 和原生实现,从而缩短实现深色主题背景所需的时间 主题。
应用必须通过在 activity 的主题中设置 android:forceDarkAllowed="true"
来选择启用 Force Dark。该属性会在所有系统和
AndroidX 提供的浅色主题,例如 Theme.Material.Light
。使用 Force Dark 时,请全面测试应用,并根据需要排除视图。
如果您的应用使用深色主题(例如 Theme.Material
),则 Force Dark 不适用于
。同样,如果应用的主题继承自 DayNight
主题,则 Force
由于系统会自动切换主题,因此未应用深色模式。
在视图上停用 Force Dark
您可以使用
android:forceDarkAllowed
布局属性,或者
setForceDarkAllowed()
。
Web 内容
如需了解如何在基于网络的内容中使用深色主题,请参阅使用 WebView 调暗网页内容的颜色。如需查看将深色主题应用于 WebView 的示例,请参阅 GitHub 上的 WebView 演示。
最佳做法
下面几个部分介绍了实现深色主题的最佳做法。
通知和微件
对于在设备上显示但您并不直接控制的界面,请确保您使用的所有视图都反映托管应用的主题背景。通知和启动器微件就是两个很好的示例。
通知
使用系统提供的通知模板,例如 MessagingStyle
。这意味着,系统将负责应用正确的视图样式。
微件和自定义通知视图
对于启动器 widget,或者如果您的应用使用自定义通知内容视图, 针对浅色主题和深色主题测试内容。
需要注意的常见陷阱包括:
- 假设背景颜色始终为浅色。
- 对文本颜色进行硬编码。
- 使用默认文本颜色时设置硬编码背景颜色。
- 使用采用静态颜色的可绘制图标。
在所有这些情况下,应使用适当的主题属性,而不是硬编码颜色。
启动屏幕
如果您的应用有自定义启动屏幕,您可能需要修改它, 反映所选的主题。
移除所有硬编码颜色,例如通过程序化方式设置为白色的背景颜色。请改用 ?android:attr/colorBackground
主题属性。
配置变更
当应用的主题发生更改(无论是通过系统设置还是 AppCompat)时,会触发 uiMode
配置变更。这意味着系统会自动重新创建 activity。
在某些情况下,您可能希望应用来处理配置变更。例如,您可能希望延迟配置变更时间,因为正在播放视频。
应用可以通过声明每个 Activity
都可以处理 uiMode
配置变更,自行处理深色主题的实现:
<activity
android:name=".MyActivity"
android:configChanges="uiMode" />
当 Activity
声明它会处理配置变更时,系统会在出现主题变更时调用其 onConfigurationChanged()
方法。
如要检查当前采用的是哪种主题背景,应用可以运行如下代码:
val currentNightMode = configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK when (currentNightMode) { Configuration.UI_MODE_NIGHT_NO -> {} // Night mode is not active, we're using the light theme. Configuration.UI_MODE_NIGHT_YES -> {} // Night mode is active, we're using dark theme. }
int currentNightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK; switch (currentNightMode) { case Configuration.UI_MODE_NIGHT_NO: // Night mode is not active, we're using the light theme break; case Configuration.UI_MODE_NIGHT_YES: // Night mode is active, we're using dark theme break; }