Android Support Library 之 夜间模式

2,618 阅读3分钟

公众号大概停更了两个周时间,1、动力不足,之前写的几篇(来一波技术公众号PullLoadMoreRecyclerView),阅读量都是不错的,却 0 赞赏。2、目前我正在陪产假,照讲有大把时间,但宝宝没有按照预产期出生,在家无聊ing,越是闲,越发现我的战斗力低,不想撸码。幸亏没有因为停更,订阅的小伙伴们就流失取关了,反而还在持续增长,这里感谢下。一直闲也不是好事,于是温故Android Design Support Library,昨晚更新了Android Design Support Library之NavigationView,本想继续更新这个系列,想想博客之前写了,还是算了(如果您想学习,可以查看我的博客),今天带来是新知识点夜间模式(其实这个早出来了,只是我一直未实践)

夜间模式实现方式

1、通过切换theme来实现夜间模式。
优点:可以匹配多套主题,并不局限于黑白模式
缺点:需要大量定义主题
详见博客:wuxiaolong.me/2015/08/19/…


2、通过修改uiMode来切换夜间模式。
修改uimode是修改Configuration,这种主题切换只限于黑白模式,没有其他模式,不需要大量定义主题,即本文介绍的内容。

效果预览

查看图片

源码地址

点击底部「阅读原文」跳转至我的github。

如何使用

第一步

(1)app/build.gradle

compile 'com.android.support:appcompat-v7:24.0.0'

(2)Activity须继承AppCompatActivity

(3)Theme.AppCompat.DayNight

 
     <!-- Customize your theme here. -->
     <item name="colorPrimary">@color/colorPrimary</item>
     <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
     <item name="colorAccent">@color/colorAccent</item>
 
 
     <item name="windowActionBar">false</item>
     <item name="windowNoTitle">true</item>
 

第二步

应用全局主题推荐在 Application 的onCreate()中进行设置
AppCompatDelegate.setDefaultNightMode(int mode);

它有四个可选值,分别是:
MODE_NIGHT_NO: 使用亮色(light)主题,不使用夜间模式
MODE_NIGHT_YES:使用暗色(dark)主题,使用夜间模式
MODE_NIGHT_AUTO:根据当前时间自动切换 亮色(light)/暗色(dark)主题
MODE_NIGHT_FOLLOW_SYSTEM(默认选项):设置为跟随系统,通常为 MODE_NIGHT_NO

第三步

动态的设定主题,需要切换主题调用:

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
//调用recreate()使设置生效
recreate();

注意事项

setDefaultNightMode()与setLocalNightMode()区别

AppCompatDelegate.setDefaultNightMode()是对整个App中theme为DayNight主题生效
getDelegate().setLocalNightMode()只对特定的组件生效

夜间资源

把夜晚主题的color等资源放在values-night中,程序在运行时就会自动调用

获取应用当前的主题

int currentNightMode = getResources().getConfiguration().uiMode
        & Configuration.UI_MODE_NIGHT_MASK;
switch (currentNightMode) {
    case Configuration.UI_MODE_NIGHT_NO:
        // Night mode is not active, we're in day time
    case Configuration.UI_MODE_NIGHT_YES:
        // Night mode is active, we're at night!
    case Configuration.UI_MODE_NIGHT_UNDEFINED:
        // We don't know what mode we're in, assume notnight
}

如果切换了主题,本想通过这个方法,下次启动程序的时候,来设置。发现并没有记住这个值,还是只能SharedPreference读取,然后根据用户设置,调用 setDefaultNightMode() 方法。

适配文字图片

尽可能的使用主题属性(theme attributes)

  • android:textColor=”?android:attr/textColorPrimary” 或者android:textColor=”?android:textColorPrimary”
    系统默认的文字颜色。在亮色(light)主题下,颜色接近黑色,在暗色(dark)主题下,颜色接近白色。

  • android:background=”?android:colorBackground”
    系统默认的背景颜色

  • ?attr/colorControlNormal. 系统默认的图标颜色

查看图片
欢迎长按上图 识别图中二维码或者微信扫一扫关注我的公众号。