Android 夜间模式实现

本次使用uiMode这种方式来实现~
修改uimode是修改Configuration,这种主题切换只限于黑白模式,没有其他模式,不需要大量定义主题。

1,需要做哪些准备

2,如何实现

3,遇到了哪些问题

一,需要做哪些准备

1,app的module 引入

implementation 'androidx.appcompat:appcompat:1.4.0'

,2,需要Activity须继承AppCompatActivity

3,清单文件 设置主题 Theme.AppCompat.DayNight

需要单独定义一个values-night 文件夹,里面要单独配置一份style文件和color文件。
style文件里滴定义colorPrimary,colorPrimaryDark,colorAccent 等主题颜色,当然普通values文件夹也要正常配置。
color文件里定义一些app里根据设计的夜间模式的颜色值

 values文件里的style:

 values文件里的color:


 

  values-night文件里的style:

values-night文件里的color:

 

 2,如何实现

首先了解哪些主题可以配置,AppCompatDelegate里包含这么几种:
MODE_NIGHT_NO: 使用亮色(light)主题,不使用夜间模式
MODE_NIGHT_YES:使用暗色(dark)主题,使用夜间模式
MODE_NIGHT_AUTO:根据当前时间自动切换 亮色(light)/暗色(dark)主题
MODE_NIGHT_FOLLOW_SYSTEM(默认选项):设置为跟随系统,通常为 MODE_NIGHT_NO

如何设定主题:
1,AppCompatDelegate.setDefaultNightMode(int mode);

2,getDelegate().setLocalNightMode(int mode)

他俩的区别:
AppCompatDelegate.setDefaultNightMode()是对整个App中theme为DayNight主题生效
getDelegate().setLocalNightMode()只对特定的组件生效,比如在activity中调用,只会对当前的activity起作用~

调用这两个方法,app会自动根据values与values-night 配置文件里的配置进行自动的变更~

调用完后要调用recreate(),重新启动页面~

AppCompatDelegate.setDefaultNightMode()效果:

点击setDefaultNightMode

 

getDelegate().setLocalNightMode()效果:

点击setLocalNightMode

 

获取应用当前主题:
 

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

 

但这个api只会记录当前操作更改后的状态,当app再启动时获取到的总是UI_MODE_NIGHT_NO

所以要结合SharedPreference来记录这个状态,保证app再次启动时能维持之前选择的状态~
application里:

 点击setDefaultNightMode 时:

三,遇到了哪些问题

当调用recreate()时,

1,在页面控件比较多时会出现闪屏的问题,

2,或者当是activity 承载多个fragment时,切换前是第二个fragment,但当执行完recreate()后,会变为第一个fragment类似问题

第一个问题,可以使用startActivity重新启动activity结合过度动画来处理,比如:

 第二个问题使用recreate(),可以在onSaveInstanceState()方法保存状态,然后再oncreate时重新取出~

 

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值