Android 使用UiMode实现夜间模式切换

夜间模式。在网上看到很多童鞋都说用什么什么框架来实现这个功能,然后仔细去看一下各个推荐的框架,发现其实都是动态换肤的,动态换肤可比夜间模式要复杂多了,未免大材小用了。说实话,我一直没用什么好思路,虽然网上有童鞋提供了一种思路是通过 setTheme 然后再 recreate Activity 的方式,但是这样带来的问题是非常多的,看起来就相当不科学(为什么不科学,后文会说)。于是,直接想到了去逆向分析那些夜间模式做得好的应用的源代码,学习他们的实现套路。所以,本文的实现思路来自于编写这些应用的夜间模式功能的童鞋,先在这里向他们表示感谢。我的手机里面使用高频的应用不少,其中简书和知乎是属于夜间模式做得相当 nice 的。先给效果图大家感受下!!

好吧,不瞎扯了,直接上套路,毕竟,有时候,套路很帮助人的!

第一步:在build.gradle中添加依赖

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

第二步:继承并应用DayNight主题

<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        -- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary
        "colorPrimaryDark">@color/colorPrimaryDark
        "colorAccent">@color/colorAccent

    style>
//attr属性设置

<resources>
    <attr name="mainBackground" format="color|reference">attr>

resources>

第三步:

新建夜间模式资源文件夹:在res目录下新建values-night文件夹,在此目录下新建colors.xml文件(在夜间模式下的应用的资源)
当然也可以根据需要新建drawable-night,layout-night等后缀为-night的夜间资源文件夹。

values目录下的colors.xml文件


<resources>
    <color name="colorPrimary">#3F51B5color>
    <color name="colorPrimaryDark">#303F9Fcolor>
    <color name="colorAccent">#FF4081color>

    <color name="textColor">#FF000000color>
    <color name="backgroundColor">#FFFFFFcolor>
resources>

values-night目录下的colors.xml文件


<resources>
    <color name="colorPrimary">#3F51B5color>
    <color name="colorPrimaryDark">#303F9Fcolor>
    <color name="colorAccent">#FF4081color>

    <color name="textColor">#FFFFFFcolor>
    <color name="backgroundColor">#3b3b3bcolor>
resources>

第四步:MyApplication 中先选择一个默认的 Mode :

public class AppConfig extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        // 默认设置为日间模式
        AppCompatDelegate.setDefaultNightMode(
                AppCompatDelegate.MODE_NIGHT_NO);
    }
}

要注意的是,这里的 Mode 有四种类型可以选择:

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

第五步:当用户点击按钮切换日/夜间时,重新去设置相应的 Mode :

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        initView();

    }
private void initView() {
        mChange = (Button) findViewById(R.id.change);
        mChange.setOnClickListener(this);
    }
 @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.change:
                // TODO 18/03/20
                int currentNightMode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
                getDelegate().setLocalNightMode(currentNightMode == Configuration.UI_MODE_NIGHT_NO ?
                        AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
                // 同样需要调用recreate方法使之生效
                recreate();

                break;
            default:
                break;
        }
    }

我们来看一下 UiMode 方案实现的效果图:
Android 使用UiMode实现夜间模式切换_第1张图片

小编最后推荐大家阅读一下这两位的讲解,比较详细

  • 对于Android日夜间模式实现的探讨
  • 夜间模式的实现套路

你可能感兴趣的:(code小生)