Android日间模式夜间模式切换(无需重启)

本文详细介绍了如何在Android应用中实现夜间模式,包括添加依赖、创建资源、设置AppCompatDelegate、监听模式切换,并逐一解决常见问题。步骤涵盖从基础配置到解决bug的过程,确保应用在不同模式下无缝切换。

第零步:添加依赖

在app 的bulid.gradle 中添加

dependencies {
    implementation 'com.android.support:appcompat-v7:27.1.1'
}

第一步:添加夜间模式资源,以-night结尾

作用:系统在不同模式会加载对应文件夹下的文件,两种模式命名相同值不相同
drawable -> drawable-night
mipmap -> mipmap-night-xxhdpi
values -> values-night

①创建夜间资源文件夹和文件
夜间资源文件夹
②修改夜间模式对应值
③在 values-night—>styles.xml 中 修改主题样式,将主题 parent 改为 Theme.AppCompat.DayNight 或者 它的子类
在这里插入图片描述

第二步:在Application中添加接收切换事件的方法,注册事件

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        EventBus.getDefault().register(this);
    }
    
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void setNight(ChangeModeBean event){
        SharedPreferences sp=getSharedPreferences("sp",0);
        //!!最重要的一步-->切换模式
        AppCompatDelegate.setDefaultNightMode(sp.getBoolean("isNightMode",false)?AppCompatDelegate.MODE_NIGHT_YES:AppCompatDelegate.MODE_NIGHT_NO);
    }
}

第三步:当前SettingActivity继承AppCompatActivity ,切换模式时发送事件

ps:一定要继承AppCompatActivity ,否则无效

	/**
	* 记录是否夜间模式、是否改变了模式
	**/
 	private boolean isNightMode, isChange;
	private void initView() {
		//switch初始化
        isNightMode = (boolean) SharedPreferencesUtils.get("isNightMode", false);
        switchNight.setChecked(isNightMode);
        //添加switch切换监听
        switchNight.setOnCheckedChangeListener((compoundButton, b) -> {
        	//模式改变时才发送事件
        	if (isNightMode == b) return;
            isChange = !isChange;
            SharedPreferencesUtils.put("isNightMode", b);
            EventBus.getDefault().post(new ChangeModeBean());
        });
	}
	
	
	@OnClick({R.id.backImageView})
    public void onViewClicked(View view) {
        switch (view.getId()) {
        	//点击返回图标,判断切换了模式就重启MainActivity
			case R.id.backImageView:
                finish();
                if (isChange) {
                    SharedPreferencesUtils.put("isChange", true);
                    appManager.finishActivity(MainActivity.class);
                    MainActivity.startActivity(this);
                    overridePendingTransition(0, 0);//无动画
                }
                break;
       }
    }

	/**
	*按系统返回键或部分设备左滑屏幕返回时,判断切换了模式就重启MainActivity
	**/
    @Override
    public void onBackPressed() {
	//  super.onBackPressed();
        finish();
        if (isChange) {
            SharedPreferencesUtils.put("isChange", true);
            appManager.finishActivity(MainActivity.class);
            MainActivity.startActivity(this);
            overridePendingTransition(0, 0);
        }
    }

ps:不要用模拟器测试,用真机测。

第四步:MainActivity切换对应Fragment

mainActivity.java:

	@Override
    protected void onCreate(Bundle savedInstanceState) {
   		 //是否刚切换完日间/夜间模式
        boolean isFromChangeMode = (boolean) SharedPreferencesUtils.get("isChange", false);
        if (isFromChangeMode) {
        	//是,切换到MineFragment
            SharedPreferencesUtils.put("isChange", false);
            viewpager.setCurrentItem(3);
        }else{
            viewpager.setCurrentItem(0);
        }
    }

mainActivity启动模式:

<activity android:name=".activity.MainActivity"
          android:launchMode="standard"/>

mainActivity主题:解决白屏,实现秒开效果

<style name="MainActivityTheme" parent="AppTheme">
      <item name="android:windowDisablePreview">true</item>
</style>

第五步:解决bug

1)解决bug1:切换夜间模式后返回 MainActivity,MainActivity 页面没有更新

—>以上已解决:当点击返回时,我们记录此时模式是否切换,让MainActivity加载时判断需要正确显示的Fragment。并且finish当前Activity,再finish MainActivity,再启动MainActivity。

2)解决bug2: 重启MainActivity时会白屏一瞬间

白屏产生的原因?
根据Activity的UI结构,启动Activity时先去加载PhoneWindow、DecorView、TitleView。此时ContentView也就是我们的layout文件还未加载,系统将屏幕填充主题默认的背景色,就会出现白屏/黑屏。

—>以上已解决:关闭掉初始化完成之前展示的默认的window(也就是白屏),实现秒开效果。

3)解决bug3: 切换模式后,部分设备左滑直接返回到设备主页面了

—>以上已解决:onBackPressed()…

参考自:
https://blog.csdn.net/lijia1201900857/article/details/82838358
https://www.jianshu.com/p/96198f766398
https://www.pianshen.com/article/35711493224/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值