第零步:添加依赖
在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/