You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 10:15:07