在项目中,有需要使用夜间模式的需求。所以,就在网络上查阅了多种资料,现在将其整理。以便以后使用和拾遗。

   网络上推荐的方式有3种,第一种是通过自己创建每一个View的night版xml文件,然后当需要进行切换时,将他们一一设置成night版的xml文档。这个方法在我第一次看到的时候,就有种感觉——真的很累,好吗?  难道真的没有可以优雅地完成日夜间模式的切换方式吗?

    于是,我搜索到了第二种解决方式,便是使用NightModeHelper第三方库。这个库可以简化我们第一种方法里较为繁琐的文件创建工作,改为只需要将修改的颜色和字体等,重新创建一个对应的colors.xml或者一个layout文件,在代码中进行申明,在需要调用的地方写下如下代码
nightModeHelp.toggle();
然后进行调用即可。

     由于是第三方库,还是有点不太想妥协,毕竟不是特别可靠。于是谷歌爸爸看不下去了,他在Support包 v23.2.0 中,更新了AppcompatDelegate这个类,这个类是一个抽象类,他的作用在于可以使具有Window.callback的activity都能够进行调用,完成通过这一方法实现的Activity的初始化或者Activity子组件的初始化。我的理解是:这样做可以使API Level较低的Android手机也能拥有高版本拥有的效果。

     回到夜间模式的整理上,在既然谷歌爸爸都提供了这一个类以及和这个类匹配的夜间模式style,那么,我就必须要试试这个方式。比较人家程序员写了那么久,还是要用一用支持一下嘛(其实就是自己懒,不想用笨办法来做)。具体是怎么做呢?首先,我把Activity继承的主题进行了修改,当变为Theme.AppCompat.DayNight这个打头的主题名时,我们就可以继承他,然后,再通过AppcompatDelegate来对夜间模式进行设置。这里有两种不同的方式,对夜间模式进行操作的方法。

第一种是 使用AppCompatDelegate.setDefaultNightMode()来进行设置夜间模式。
这其中的参数有四种选择
MODE_NIGHT_NO 日间模式
MODE_NIGHT_YES 夜间模式
MODE_NIGHT_AUTO 根据时间自动切换日夜间模式
MODE_NIGHT_FOLLOW_SYSTEM 默认模式

AppCompatDelegate.setDefaultNightMode();
在这种方式下,系统会改变模式的参数,当然,是在整个APP中进行调整,但是有个问题,也就是使用这种方式,虽然修改了参数,但是并不能在当前页面马上生效,怎么办呢?可以在语句后添加recreate()来对当前activity重绘,那么就能够完成日夜间模式切换。(但据我的实践,发现这种操作在进行多次后就会出现问题,可能是因为我写的有问题,如果要马上改变当前界面的风格,使用第二种方式会更稳妥一些)

第二种是 getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
这种方式的优点是可以直接将整个界面在设置参数过后直接进行重绘。这两种方法可以搭配使用,这样效果比较好,注意这个方法只对当前activity有效,对其他无效。

如果你对谷歌爸爸的夜间主题配色不满意,那也可以自己写,as you like。关于夜间模式就总结那么多。如果有笔误或者理解错误的地方请见谅。