Android一种实现夜间模式方式,同时解决调用recreate() 时闪屏问题

    最近项目中要实现夜间模式,调研了几种Android的夜间模式实现方式,都是需要动态的改变ui界面引用到color、drawable等资源文件。由于这个项目是迭代了比较多版本的,ui界面比较多,项目也比较大了要每个界面都去重新梳理一遍字体颜色的改变逻辑,drawable资源的引用逻辑这个工作量是很大的,但是没办法要实现不同的界面风格这个工作是一定要做的。有一些夜间模式的实现方式是通过下载zip包来拿到不同的皮肤资源,有些是通过下载apk文件再拿到它的context获取里面drawable等资源。这些都需要自己去另外写资源的下载和加载逻辑,当然这种实现方式可以更换多种皮肤,如果是项目从0到1开始开发这种方式是不错的。但是考虑到时间成本就选了使用Support Library包中添加的夜间模式主题,简单粗暴。

    首先activity继承于AppCompatActivity ,然后将style.xml中的主题样式改为Theme.AppCompat.DayNight,最后就是在application中调用AppCompatDelegate.setDefaultNightMode(int mode)设置日夜间模式,其中mode 有4个值可选分别是:
                    MODE_NIGHT_NO: 使用亮色(light)主题,不使用夜间模式
                    MODE_NIGHT_YES:使用暗色(dark)主题,使用夜间模式
                    MODE_NIGHT_AUTO:根据当前时间自动切换 亮色(light)/暗色(dark)主题
                    MODE_NIGHT_FOLLOW_SYSTEM(默认选项):设置为跟随系统,通常为 MODE_NIGHT_NO
   接下来就是苦逼的更换资源工作了。需要在对应的资源目录下创建-night目录,如:drawable 对应夜间模式 drawable-night,value对应夜间模式 value-night,而且里面的item项的文件名要一致。

     在调用AppCompatDelegate.setDefaultNightMode(int mode)更改模式后需要调用recreate()方法才会生效,这时候会有个坑,就是会闪屏。像华为荣耀这些手机会闪的很厉害,小米会相对好点。后来想了个掩盖闪屏的方案,在调用recreate()方法前先打开一个半透明的activity,然后延迟1s左右消失,给它一个透明度渐变消失的动画,效果还不错。如下面的代码:


        if (isNightMode != VoiceApplication.getInstance().isAppNightMode()) {
            startActivity(new Intent(this, NightModeChangeMaskActivity.class));
            overridePendingTransition(R.anim.alpha_in, R.anim.alpha_out);
            recreate();
            isNightMode = VoiceApplication.getInstance().isAppNightMode();
        }
public class NightModeChangeMaskActivity extends BaseActivity {

    @Override
    protected int getStatusBarColorRes() {
        return R.color.night_mode_mask_color;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_night_mode_change_mask);
        Single.timer(1000, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
                .compose(bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(aLong -> {
                    finish();
                });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void finish() {
        super.finish();
        overridePendingTransition(0, R.anim.alpha_out);
    }
}

这里主要是记录下实现夜间模式的实现方式和日夜间解决切换时闪屏的解决方案,做个笔记吧。

你可能感兴趣的:(Android)