深色主题适用于 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 和原生实现,从而缩短实现深色主题背景所需的时间 主题。
应用必须通过在以下位置设置 android:forceDarkAllowed="true"
来选择启用 Force Dark
activity 的主题。该属性会在所有系统和
AndroidX 提供的浅色主题,例如 Theme.Material.Light
。使用
Force Dark,全面测试应用,并根据需要排除视图。
如果您的应用使用深色主题(例如 Theme.Material
),则 Force Dark 不适用于
。同样,如果应用的主题继承自 DayNight
主题,则 Force
由于系统会自动切换主题,因此未应用深色模式。
在视图上停用 Force Dark
您可以使用
android:forceDarkAllowed
布局属性,或者
setForceDarkAllowed()
。
Web 内容
如需了解如何在基于网络的内容中使用深色主题,请参阅使用 WebView 调暗网页内容的颜色。深色主题示例 ,请参阅 WebView 演示 GitHub ,了解所有最新动态。
最佳做法
下面几个部分介绍了实现深色主题的最佳做法。
通知和微件
对于在设备上显示但您并不直接控制的界面, 请确保您使用的所有视图都能反映托管应用的主题。两个示例分别是 通知和启动器微件。
通知
使用系统提供的通知模板,例如 MessagingStyle
。这个
表示由系统负责应用正确的视图样式。
微件和自定义通知视图
对于启动器 widget,或者如果您的应用使用自定义通知内容视图, 针对浅色主题和深色主题测试内容。
需要注意的常见误区包括:
- 假设背景颜色始终为浅色。
- 对文本颜色进行硬编码。
- 使用默认文本颜色时设置硬编码背景颜色。
- 使用采用静态颜色的可绘制图标。
在所有这些情况下,请使用适当的主题属性,而不是硬编码的主题属性 颜色。
启动屏幕
如果您的应用有自定义启动屏幕,您可能需要修改它, 反映所选的主题。
移除所有硬编码颜色,例如以编程方式设置为
白色。请改用 ?android:attr/colorBackground
主题属性。
配置变更
当应用的主题通过系统设置或 AppCompat 发生变化时,
触发 uiMode
配置更改。这意味着系统会自动重新创建 activity。
在某些情况下,您可能希望应用来处理配置变更。例如,您可能希望延迟配置变更时间,因为正在播放视频。
应用可以通过以下方式处理深色主题的实现:声明每个
Activity
可以处理 uiMode
配置变更:
<activity
android:name=".MyActivity"
android:configChanges="uiMode" />
当 Activity
声明它会处理配置变更时,其
onConfigurationChanged()
方法。
如要检查当前采用的是哪种主题背景,应用可以运行如下代码:
Kotlin
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. }
Java
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; }