Android中仅当前Activity主题变更其他页面无效,如何通过MainActivity实现全局明暗模式切换
实现全应用深色/浅色模式同步切换方案
问题原因
你当前仅在MainActivity中调用了当前页面的代理设置夜间模式,没有持久化存储主题状态,其余Activity启动时也没有主动应用全局主题配置,因此仅当前页面生效。
实现步骤
步骤1:新增主题状态持久化逻辑
使用SharedPreferences存储用户选择的主题模式,确保应用重启也能保留配置。
步骤2:封装BaseActivity作为所有Activity的父类
所有业务Activity继承该基类,在生命周期初始化阶段主动读取存储的主题状态并应用,无需每个页面重复写适配逻辑。
步骤3:修改MainActivity的切换逻辑
切换模式时同步更新存储的状态,触发全局生效。
对应实现代码
1. BaseActivity基类代码
import android.os.Bundle; import android.content.SharedPreferences; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatDelegate; public class BaseActivity extends AppCompatActivity { private SharedPreferences sp; private int currentNightMode; @Override protected void onCreate(Bundle savedInstanceState) { sp = getSharedPreferences("app_config", MODE_PRIVATE); // 必须先应用主题再执行父类onCreate逻辑,否则样式不生效 applyNightMode(); super.onCreate(savedInstanceState); currentNightMode = getResources().getConfiguration().uiMode & android.content.res.Configuration.UI_MODE_NIGHT_MASK; } @Override protected void onResume() { super.onResume(); // 从后台返回/切换页面时判断主题是否变更,变更则自动刷新页面 int newNightMode = getResources().getConfiguration().uiMode & android.content.res.Configuration.UI_MODE_NIGHT_MASK; if (currentNightMode != newNightMode) { recreate(); return; } applyNightMode(); } private void applyNightMode() { boolean isNightMode = sp.getBoolean("night_mode", false); getDelegate().setLocalNightMode(isNightMode ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO); } }
2. 修改后的MainActivity代码
import android.os.Bundle; import android.widget.CompoundButton; import android.widget.ToggleButton; import androidx.appcompat.app.AppCompatDelegate; // 注意改为继承BaseActivity public class MainActivity extends BaseActivity { ToggleButton day_night; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); day_night = findViewById(R.id.day_night); // 初始化按钮状态和存储的主题配置保持一致 boolean isNightMode = getSharedPreferences("app_config", MODE_PRIVATE).getBoolean("night_mode", false); day_night.setChecked(isNightMode); day_night.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // 持久化存储主题状态 getSharedPreferences("app_config", MODE_PRIVATE) .edit() .putBoolean("night_mode", isChecked) .apply(); // 应用到当前页面 getDelegate().setLocalNightMode(isChecked ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO); } }); } }
注意事项
- 所有业务Activity都要改为继承
BaseActivity,不要直接继承AppCompatActivity - 应用的主题要继承
Theme.MaterialComponents.DayNight或者Theme.AppCompat.DayNight系列的父主题,才能自动适配深浅模式的样式 - 如果切换后需要立刻刷新后台栈中已经打开的其他Activity,可在切换逻辑后主动调用栈内Activity的
recreate()方法,上述BaseActivity中onResume的判断逻辑已经可以覆盖用户返回旧页面的常规场景
内容的提问来源于stack exchange,提问作者user17300427
相关产品推荐
相关产品推荐

