夜间模式实践(一)

为什么说是实践一呢? 因为这次写的只是实现夜间模式最基本的方式,当然会有一些瑕疵。

因为最近手机和电脑的模拟器一起抽风……就不给大家看效果了,就是跟知乎或者知乎日报的夜间模式差不多

直接上代码:

  • 首先添加依赖:

    compile ‘com.android.support:appcompat-v7:23.3.0’

  • 配置相应的模式

<style name="AppTheme" parent="AppTheme.NoActionBar">
        <!--状态栏颜色-->
        <item name="colorPrimaryDark">@color/colorMain</item>
        <!--Toolbar颜色-->
        <item name="colorPrimary">@color/colorMain</item>
        <!--返回键样式-->
        <item name="drawerArrowStyle">@style/AppTheme.DrawerArrowToggle</item>
    </style>
    <style name="AppTheme.NoActionBar" parent="Theme.AppCompat.DayNight">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

因为我设置了NoActionBar 所以只要继承Theme.AppCompat.DayNight就好了。
然户在application节点设置

android:theme="@style/AppTheme"
  • 设置夜间/白天模式的资源
    主要是color和string
    在res下新建一个values-night文件夹,然后新建colors.xml和strings.xml
    设置相应的颜色和字符资源 比如:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#222222</color>
    <color name="colorPrimaryDark">#2B2B2B</color>
    <color name="colorAccent">#EDEDED</color>

    <color name="colorMain">#222222</color>
    <color name="colorGray">#8D8D8D</color>
    <color name="colorBlack">#2B2B2B</color>
    <color name="colorGrayWhite">#222222</color>
    <color name="colorBG">#343434</color>
    <color name="colorItemBG">#404040</color>
    <color name="colorWord">#DDDDDD</color>
</resources>

注意: 这里所有的name必须和values目录下的colors.xml里的相同,在切换到夜间模式后才能正确的切换资源。

  • 模式切换:
private void reSetMode() {
        boolean isNightMode = PrefUtils.getBoolean(MainActivity.this, "isNightMode", false);
        if (isNightMode) {
            PrefUtils.setBoolean(MainActivity.this,"isNightMode",false);
            getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        } else {
            PrefUtils.setBoolean(MainActivity.this,"isNightMode",true);
            getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
        }
        recreate();
    }

解释一下 我在SharePreference中保存了一个值来标记当前是夜间模式还是白天模式 (PrefUtils是一个工具类就是操作SharePreference 大家不用在意)

MODE_NIGHT_NO: 不使用夜间模式
MODE_NIGHT_YES:使用夜间模式
MODE_NIGHT_AUTO:根据当前时间自动切换
MODE_NIGHT_FOLLOW_SYSTEM(默认):跟随系统,一般为MODE_NIGHT_NO

最后注意一定要recreate(); 不然是不会生效的,这也是这种方法算是一个不足的地方,因为在重启Activity时会有一瞬间的闪烁,效果就不好了。当然是有办法解决的,这里不做说明,之后会写,主要思想是保存一帧做透明度渐变

  • 最后为了在关闭应用后再打开仍然保存之前的模式,需要在Application中做处理:新建一个MyApplication.java
public class MyApplication extends Application {


    public static boolean isNightMode;

    @Override
    public void onCreate() {
        super.onCreate();
        isNightMode = PrefUtils.getBoolean(this.getApplicationContext(), "isNightMode", false);
        if (isNightMode) {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
        } else {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        }
    }
}

很简单 就是在启动的时候根据之前保存的标记变量来设置夜间/白天模式
在清单文件中

<application
        android:name=".MyApplication"

基本上就是这样,看过很多方式来实现夜间模式,个人觉得这种是最好理解和实现的。当然有一点不足就是reCreate时候的一瞬间闪烁。后边介绍怎么解决这个问题。

有写的不对的地方 欢迎指正

posted @ 2016-10-14 12:47  Z漫步  阅读(288)  评论(0编辑  收藏  举报