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

Android Studio开发深色模式切换功能出现无限循环如何解决

Android深色模式切换问题修复方案

问题1:应用重启后无法自动适配深色模式

根因

AppCompatDelegate.setDefaultNightMode() 是进程级配置,应用重启后配置会重置,你当前仅在设置页的onCreate中初始化该配置,启动时未进入设置页就不会触发全局模式设置。

修复步骤

  1. 自定义全局Application类,在应用启动时就读取SharedPreferences配置设置夜间模式:
public class MyApp extends Application {
    public static final String MyPREFERENCES= "nightModePrefs";
    public static final String KEY_ISNIGHTMODE = "isNightMode";

    @Override
    public void onCreate() {
        super.onCreate();
        SharedPreferences sp = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);
        boolean isNightMode = sp.getBoolean(KEY_ISNIGHTMODE, false);
        if (isNightMode) {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
        } else {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
        }
    }
}
  1. 在AndroidManifest.xml的application标签中添加android:name=".MyApp",指定自定义Application。

问题2:切换模式后无限循环

根因

两处逻辑冲突导致循环触发:

  • 调用setDefaultNightMode()后系统会自动重建当前Activity,你又额外手动调用了recreate(),导致重复重建
  • 原有代码中checkNightModeActivated()调用darkSwitch.setChecked()时会触发OnCheckedChangeListener回调,哪怕是代码主动设置的状态,也会再次走切换逻辑,形成死循环

修复步骤

调整设置页代码逻辑:

  1. 移除OnCheckedChangeListener中的手动recreate()调用
  2. 先给Switch设置初始状态,再绑定状态监听,避免代码设置状态时触发不必要的回调
  3. 调整后的设置页核心代码如下:
private Switch darkSwitch;
public static final String MyPREFERENCES= "nightModePrefs";
public static final String KEY_ISNIGHTMODE = "isNightMode";
SharedPreferences sharedPreferences;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_setting);
    Log.d(TAG_LIFECYCLE, "In the activity_setting onCreate() event");

    fbAuth = FirebaseAuth.getInstance();
    fbStore = FirebaseFirestore.getInstance();
    userID = fbAuth.getCurrentUser().getUid();

    sharedPreferences = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);
    darkSwitch = findViewById(R.id.swDark);

    // 先读取状态设置Switch,此时还没设置监听,不会触发回调
    boolean isNightMode = sharedPreferences.getBoolean(KEY_ISNIGHTMODE, false);
    darkSwitch.setChecked(isNightMode);

    // 再设置监听,仅响应用户点击操作
    darkSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if(isChecked) {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                saveNightModeState(true);
                Log.d(TAG_LIFECYCLE, "In the setting darkModeOn event");
            } else {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                saveNightModeState(false);
                Log.d(TAG_LIFECYCLE, "In the setting darkModeOff event");
            }
        }
    });

    // 原有底部导航逻辑保持不变
    BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_nav);
    bottomNavigationView.setSelectedItemId(R.id.settingActivity);
    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
            switch (menuItem.getItemId()) {
                case R.id.mainActivity:
                    startActivity(new Intent(getApplicationContext(),MainActivity.class));
                    overridePendingTransition(0,0);
                    return true;
                case R.id.mapActivity:
                    startActivity(new Intent(getApplicationContext(),MapActivity.class));
                    overridePendingTransition(0,0);
                    return true;
                case R.id.userInfoActivity:
                    startActivity(new Intent(getApplicationContext(),UserInfoActivity.class));
                    overridePendingTransition(0,0);
                    return true;
                case R.id.settingActivity:
                    return true;
            }
            return false;
        }
    });
}
private void saveNightModeState(boolean nightMode) {
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putBoolean(KEY_ISNIGHTMODE, nightMode);
    editor.apply();
}

注意:如果你的Activity在AndroidManifest.xml中配置了android:configChanges="uiMode",需要移除该配置,否则系统不会自动触发Activity重建适配新的模式。

内容的提问来源于stack exchange,提问作者zico

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 11:15:04