当前位置:首页 > 资讯 > 正文

小米手机深色模式适配说明q手机「小米手机深色模式适配说明」

小米手机适配说明

Android 10 (API 级别 29) 及更高版本中提供深色主题背景。深色主题背景具有诸多优势:

深色主题背景同时适用于 Android 系统界面和在设备上运行的应用。在 Android 10 (API 级别 29) 及更高版本中,您可以通过以下三种方法启用深色主题背景:

可参考:https://developer.android.com/guide/topics/ui/look-and-feel/darktheme#top_of_page

深色模式是一种将屏幕主色调转为深色的模式。如下图MIUI10界面为例,上图是正常浅色背景,下图为MIUI深色模式。

小米手机深色模式适配说明
小米手机深色模式适配说明

用户在MIUI中有两个方式可以打开深色模式:1.设置-显示-深色模式 2.下拉控制中心 中可以开启,开启后将全局变黑如上图显示:

小米手机深色模式适配说明
小米手机深色模式适配说明
小米手机深色模式适配说明

对于的应用来说,我们会优先启用应用的深色模式。未接入的应用,则会通过算法进行反色。适配方式将在第三部分详细描述。如果用户不希望某个应用被反色,用户可以手动关闭该应用的反色功能,见下方:

小米手机深色模式适配说明
小米手机深色模式适配说明

目前已有众多知名头部三方应用适配了深色模式,例如微信、QQ、爱奇艺、优酷、知乎、小红书、钉钉等。

我们强烈建议您为您的应用适配深色模式,主要有如下原因:

作为一种全新的潮流,黑色界面受到众多用户、尤其是年轻用户的欢迎。目前,各大安卓系统、iOS系统都已经支持深色模式,众多主流头部应用也已适配或正在适配深色模式。                

深色背景下,文字、图片、视频都能更清晰地呈现,尤其是暗光环境下。对于浏览器、资讯和视频类,深色可以让用户沉浸其中,为应用贡献更多的使用时长:对于使用时段是晚上的应用,这一特性更加明显。                                               

省电是用户最关注的性能之一。低电情况下,用户更青睐使用深色模式的应用。根据小米实验室测试数据:

OLED屏幕100%亮度下,深色模式耗电相比浅色模式,最高降低83%;

OLED屏幕50%亮度下,深色模式耗电相比浅色模式,最高降低50%。

小米手机深色模式适配说明

适配方式有两种:

在适配前,开发者需要考虑是否在自有应用内增加深色模式开关。我们建议的方式:

目前已有三方应用如下(左 小红书 右 QQ),仅供参考:

小米手机深色模式适配说明
小米手机深色模式适配说明

适配深色模式资源需要设计师先对所有页面设计深色页面,再由开发完成深色模式资源开发。

优点:在所有安卓版本、所有手机厂商用户均可以使用,且体验较好。

开发者可基于谷歌深色模式适配标准进行适配:https://developer.android.com/guide/topics/ui/look-and-feel/darktheme#top_of_page

已经适配过的页面要将ForceDarkAllowed()​参数值设置为false,若整个主题均已适配深色模式,则需要将这个主题的ForceDarkAllowed()参数值设置为false。

小米手机深色模式适配说明
小米手机深色模式适配说明
小米手机深色模式适配说明
小米手机深色模式适配说明
小米手机深色模式适配说明
小米手机深色模式适配说明
小米手机深色模式适配说明
小米手机深色模式适配说明
小米手机深色模式适配说明
小米手机深色模式适配说明
小米手机深色模式适配说明

其余适配建议详见设计文档:附件1-小米深色模式配色标准设计文档。

您还可以使用 MaterialComponent 的深色主题背景:

这会将应用的主要主题背景与系统控制的夜间模式标记相关联,并将应用的默认主题背景设置为深色主题背景(如果已启用)。详细内容见:https://developer.android.com/guide/topics/ui/look-and-feel/darktheme#force_dark

从开发的角度说,就是打开夜间模式后,系统会优先从xxx-night资源中寻找资源并替换。
Android系统从2.2开始就已经⽀支持了了DarkMode,其对应接口是名为“uimode”的系统服务,DarkMode所使⽤用到的接口方法是:setNightMode、getNightMode分别对应设置夜间模式和获取设置状态。

从uimode服务dump出来的信息可以判断:

mNightMode的取值:0 → AUTO; 1 → NO; 2 → YES另外,在Android O开始,Android⽀支持adb命令启动和停⽤用DarkMode,具体命令是:adb shell cmd uimode night <auto | yes | no>

O以前的机型,只能通过代码调用uimode接口启动和停用DarkMode。需要注意的是,miui虽然从level 16开始支持DarkMode,但是并不意味着miui之前的版本不能切换DarkMode,用户完全可以通过命令或者代码调用系统接口,启动和关闭DarkMode。而Setting中的开关是阻⽌不了的,除⾮MIUI对这个权限进行收紧。   

MIUI SDK从level 16开始,支持DarkMode,所以的支持DarkMode,是指MiuiSDK增加了新的主题,DayNight,来自适应的适配Light和Dark主题。其实在16之前的SDK上,Light和Dark主题都是一直存在的,只是没有一个自动适配的机制存在,而且Dark主题存在一些Bug,并不是它应该是的样⼦。适配过程中,存在一些APP,之前就是在Dark主题下进行的开发,那么在sdk level 16以后,发现Dark模式存一些问题,比如弹窗变成了⿊⾊,均是因为Dark主题修改造成的。附录中会给出SDK针对Dark和Light进行的改动,包括所有受影响的资源和主题样式修改。

重点说明⼀下接⼊和使⽤⽅式。这⾥除了Theme.Light.DarkActionBar这个主题以外,所有Light(Dark)主题均有对应的DayNight主题。

代码接⼊方式:可以直接将使⽤MiuiSdk的Light或者Dark主题的地方,替换成DayNight主题,⽐如:将

Java代码中:将使⽤Light主题的所有地⽅miui.R.style.Theme_Light替换成miui.R.style.Theme_DayNight

于是,miui sdk中的Theme.DayNight就接入完成,在APP中可以直接使⽤Theme.DayNight.<…>主题。针对之前的miui:Theme.Light主题或者miui:Theme.Dark主题,均有对应的Dark或者Light主题。所以,如果需要适配自动切换夜间和日间模式,只要替换成对应的DayNight主题即可,DayNight主题负责⾃动切换两种(Dark和Light)主题。

全局反色利用安卓Q上提供的forcedark能力可以直接反色,对于开发者来说较为友好。

可以在安卓Q手机上,打开以下开关即可体验安卓Q反色能力,查看本应用反色后的情况。开关位置如下:

小米手机深色模式适配说明

Android 10 提供 Force Dark 功能。一如其名,此功能可让开发者快速实现深色主题背景,而无需明确设置 ​DayNight​ 主题背景。如果您的应用采用浅色主题背景,则 Force Dark 会分析应用的每个视图,并在相应视图在屏幕上显示之前,自动应用深色主题背景。有些开发者会混合使用 Force Dark 和本机实现,以缩短实现深色主题背景所需的时间。应用必须选择启用 Force Dark,方法是在其主题背景中设置 ​android:forceDarkAllowed=”true”​。此属性会在所有系统及 AndroidX 提供的浅色主题背景(例如 ​Theme.Material.Light​)上设置。使用 Force Dark 时,您应确保全面测试应用,并根据需要排除视图。如果您的应用使用深色主题背景(例如​Theme.Material​),则系统不会应用 Force Dark。同样,如果应用的主题背景继承自 DayNight​主题背景,则系统不会应用 Force Dark,因为会自动切换主题背景。

在MIUI12上推出全局的深色模式,所有系统应用和主流三方应用适配。在MIUI12上用户开启深色模式后将默认开启全局反色。要达到的效果:系统切换到深⾊模式以后,应⽤也随之切换到深色模式,这是我们这次MIUI适配深色模式要达到的目标,也是我们对每个系统应⽤的要求。

适配的⽅法有三种:                                          

目前只有Android Q深色模式支持全局反色:Android Q上提供了两种实现深色模式的⽅式:深色主题和全局反⾊。

深⾊主题即Theme.AppCompat.DayNight或者Theme.MaterialComponents.DayNight。深⾊主题是Android官⽅提供的实现深色模式的一种方法,应用也可以其它自己的方法实现深色模式。深⾊主题起作用后,将会加载-night⽬目录下的资源,如果没有找到,那么加载默认资源。对于标准控件,如果应用不提供深色模式的资源,系统也会提供一套默认的深色资源(不过比较难看,基本不可用)全局反色即ForceDark,系统会根据一套算法,计算出每个View属于前台还是后台。对于前台View,会使其变亮,对于后台View,会使其变暗,⽽不需要开发者提供两套资源。具体的原理可以移步Android Q Force Dark调研。如果一个activity使⽤了深色模式,那么全局反色对其将不生效。    

打开系统的深⾊模式,看看⾃⼰应用中那些⻚面有没有问题,一般可以分为三类:

A.适配了深色模式没有问题

B.没有适配深色模式的

C.适配了深⾊模式但是有问题的

对于所有的A,请务必禁用全局反色,否则全局反色可能会和已有的深⾊模式效果冲突。对于所有的B,可以设置 <item name=”android:forceDarkAllowed”>true</item> ,然后可以打开全局反色,观察有没有问题。没有问题的,那就适配完成了,问题⽐较⼤的归为D。

对于所有的D,分析问题的原因,是反色本身的问题还是⾃己应⽤导致的,⽐如布局存在有问题,有图片、webVIew等。其他的看下能不能通过调整布局等最后还是通过全局反⾊简单解决,剩下统一归为C。

对于C,看看是不是原来的适配方法有问题,有没有必要采用新的适配⽅法、框架,可不可以采用系统的深色主题等重新适配。                                              

打开系统深色模式,重新测试所有页⾯。

比较理想的做法是:建议采用深色主题和全局反色相结合的方式。整个应用用的主题使用DayNight,设置<item name=”android:forceDarkAllowed”>false</item>。对于已经⽀持深色主题或者用其他方法实现了深⾊模式的⻚面,没必要再支持全局反⾊,务必禁⽤。对于需要使用反⾊的⻚面,使⽤Light主题,设<itemname=”android:forceDarkAllowed”>true</item>。其他⻚面单独适配。                                             

深色主题在Android Q之前就是已经有了的,只不过其在Android Q上得到了了加强。一个activity如果想使用深色主题,让其主题继承于DayNight主题或者让整个应用的主题继承于DayNight主题即可。不过,上⾯的做法只适合跟随系统变化的需求,如果有高级的需求,⽐如应用想要主动切换到深⾊色主题或者不跟随系统变化,而是让⽤户选择,那么需要这样做:

1.监听UImode的变化。manifest中 activity 设置属性 android:configChanges=”uiMode”,并重写onConfigurationChanged。注意,声明了configChanges系统将不不会重建对应的activity,⽽而是回调onConfigurationChanged,需要activity⾃己处理变化的情况

2.让Activity继承于AppCompatActivity,这样子可以通过AppCompatDelegate.setDefaultNightMode(mode) 设置当前activity的mode,通过AppCompatDelegate.getDefaultNightMode()获取当前设置的mode。系统可以选择的mode有四种,具体解释可以看下面第1篇文章。

3.用户选择夜间模式的时候,保存用户选择的模式到SharedPreferences,调用recreate()重启activity,注意recreate()是重新创建activity,会回调所有生命周期方法。

4.activity启动的时候,取出之前保存的模式,通过AppCompatDelegate.setDefaultNightMode(mode) 进行当前activity的mode。                                            

5.系统UImode发⽣变化的时候,即onConfigurationChanged时,获取系统当前的UImode,根据应用⾃身的逻辑判断需不需要改变当前activity的mode,如果需要改变重复第3、4步。

切换到深⾊模式时,资源应用的顺序:                                  

所以,凡是应用⾃己提供资源了的,那就提供两套,要么就全部⽤用系统的默认资源。如果一个应⽤没有使用DayNight主题,那么只会变化应用提供的-night深⾊资源,其他不会变化,系统也不会应⽤标准控件的默认深色资源。

具体实现,可以参考:  

有两种方式,⼤同小异,相信大家能看得懂。

⾸先来看下全局反色生效前提:

系统端:1.开启深色模式

应用端:1.activity对应的主题是Light的 2.对应的控件允许全局反色,默认是forceDarkAllowedDefault,这个值由系统属性debug.hwui.force_dark决定,debug.hwui.force_dark⼜是由全局反⾊的开关控制,默认是关闭的。         

以上几点缺⼀不可,需要详细说明几点是:

1.实现了深色主题的activity是不会受全局反色的影响,前面说了,深⾊主题是DayNight,不属于Light

2.如果一个控件没有申明forceDarkAllowed,那么forceDark是否⽣效取决于全局反色是否开启,如果全局反色开启,那么forceDark生效,否则不生效;

如果一个控件声明了forceDarkAllowed = false,那么无论如何都不会生效;

如果一个控件声明了forceDarkAllowed = true,那么只要开启深色模式,全局反色就会⽣效。             

3.forceDarkAllowed可以在主题xml中申明,也可以在代码中动态设置,动态设置可以具体到某⼀个view,后者会覆盖前者。遵循覆盖原则,即子View的声明会覆盖父View的声明,activity的会覆盖这个应⽤的申明。

适配全局反色的步骤:                                                

1.compileSdkVersion 设为29, 否则会编译失败,targetSdkVersion 貌似没有要求。

2.对于需要使用forceDark的activity,务必让其实现Light主题,Dark主题、DayNight主题都不会⽣效。

3.在activity的主题中申明<item name=”android:forceDarkAllowed”>true</item> 或者 在onCreate中,在setContentView之前,调⽤getWindow().getDecorView().setForceDarkAllowed(allowed)。

最后提供demo,需要的可以参考一下,源码:https://github.com/CQULittleMing/AndroidDemo/tree/master/demo

操作路径:  View – View 下面最后的两个。     

设置是否⽀持全局反色有静态和动态两种方法:                                              

静态方式就是对应用或者activity的主题中声明<item name=”android:forceDarkAllowed”>true</item> 或者 <item name=”android:forceDarkAllowed”>false</item>;

动态⽅法是调用View.setForceDarkAllowed(true)或者View.setForceDarkAllowed(false),对DecorView设置可以对整个窗口起作⽤。

有任何问题可以随时联系我们:

商务合作:liushuo3@xiaomi.com

产品问题:zhangyanan10@xiaomi.com