今天分享第一个深色主题。
1,简介:
Android 10 (API level 29) 及更高版本中提供深色主题背景。深色主题背景具有诸多优势:
1,可大幅减少耗电量(具体取决于设备的屏幕技术)。
2,为弱视以及对强光敏感的用户提高可视性。
3,让所有人都可以在光线较暗的环境中更轻松地使用设备。
深色主题背景同时适用于 Android 系统界面和在设备上运行的应用。
在 Android 10 (API level 29) 及更高版本中,您可以通过以下三种方法启用深色主题背景:
使用系统设置(Settings -> Display -> Theme)启用深色主题背景。
使用“快捷设置”图块,从通知托盘中切换主题背景(启用后)。
在 Pixel 设备上,选择“省电模式”将同时启用深色主题背景。其他原始设备制造商 (OEM) 不一定支持这种行为
2,实现方式
通过添加一个dark主题或启用Force dark,为启用系统范围的dark主题的用户提供一致的体验。
(1),直接使用深色主题,让app主题继承暗色风格主题(新建一个res/values-night)
(2),Force Dark
Android 10 提供 Force Dark 功能。一如其名,此功能可让开发者快速实现深色主题背景,而无需明确设置 DayNight 主题背景。
如果应用采用浅色主题背景,则 Force Dark 会分析应用的每个视图,并在相应视图在屏幕上显示之前,自动应用深色主题背景。有些开发者会混合使用 Force Dark 和深色主题实现,以缩短实现深色主题背景所需的时间。
应用选择启用 Force Dark,方法是在其主题背景中设置 android:forceDarkAllowed="true"。此属性会在所有系统及 AndroidX 提供的浅色主题背景(例如 Theme.Material.Light)上设置。
当然也可以在java中使用setForceDarkAllowed()方法设置。
3,我的源码分析过程
(1),设置入口查哪里触发
(2)查系统api UiModeManager.java类
同时可以看到可以设置几种模式
(3),查找服务类实现
然后会在updateLocked方法中发出广播,
getContext().sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
mResultReceiver, null, Activity.RESULT_OK, null, null);
并更新系统配置,updateConfigurationLocked(); 在这个配置属性中多了一个uiMode属性。
mConfiguration.uiMode。
这个属性理解可以参考方向旋转属性 。auto-rotate旋转一样,在触发时候去重建Activity在更新app主题。
所以需要监控这个属性,可以在AndroidManifest.xml加入这个属性
android:name=".MyActivity"
android:configChanges="uiMode" />
然后可以在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; }