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</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>

    </style>
//attr属性设置
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="mainBackground" format="color|reference"></attr>

</resources>

第三步:

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

values目录下的colors.xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color><!--标题栏-->
    <color name="colorPrimaryDark">#303F9F</color><!--状态栏-->
    <color name="colorAccent">#FF4081</color><!--编辑颜色-->

    <color name="textColor">#FF000000</color>
    <color name="backgroundColor">#FFFFFF</color>
</resources>

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

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color><!--标题栏-->
    <color name="colorPrimaryDark">#303F9F</color><!--状态栏-->
    <color name="colorAccent">#FF4081</color><!--编辑颜色-->

    <color name="textColor">#FFFFFF</color>
    <color name="backgroundColor">#3b3b3b</color>
</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 方案实现的效果图:
这里写图片描述

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

  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值