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

Android:切换暗黑主题时当前Fragment自动跳转为首个Fragment问题

问题解决:主题切换时保留Bottom Navigation的当前Fragment状态

问题场景

使用Bottom Navigation管理Fragment的Activity,通过选项菜单切换主题时,当前显示的Fragment会自动切换为首个Fragment,无法保持当前状态。当前主题切换代码如下:

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.light_mode -> {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
            sharedPrefs = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
            val editor = sharedPrefs.edit()
            editor.putBoolean(THEME_PREF_KEY, false)
            editor.apply()
            true
        }
        R.id.dark_mode -> {
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
            sharedPrefs = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
            val editor = sharedPrefs.edit()
            editor.putBoolean(THEME_PREF_KEY, true)
            editor.apply()
            true
        }
        R.id.log_out -> {
            logout()
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

问题原因

调用AppCompatDelegate.setDefaultNightMode()会触发Activity重启以应用新主题,而Activity重启后,Bottom Navigation会默认选中第一个菜单项,导致对应的Fragment被重新加载,覆盖了之前显示的Fragment。

解决方案

  • 保存当前选中项:切换主题前,把Bottom Navigation当前选中的菜单项ID存入SharedPreferences。
  • 恢复选中状态:在Activity的onCreate方法中,读取保存的选中ID,设置Bottom Navigation的选中状态并切换到对应Fragment。
  • 优化重复代码:提取SharedPreferences操作逻辑,避免冗余。

修改后的代码

1. 主题切换时保存当前选中项

// 定义保存选中项的Key
private const val SELECTED_NAV_ITEM_KEY = "selected_nav_item"

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    val sharedPrefs = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
    val editor = sharedPrefs.edit()

    return when (item.itemId) {
        R.id.light_mode -> {
            // 保存当前选中的Bottom Navigation项
            editor.putInt(SELECTED_NAV_ITEM_KEY, bottomNavigationView.selectedItemId)
            editor.putBoolean(THEME_PREF_KEY, false)
            editor.apply()
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
            true
        }
        R.id.dark_mode -> {
            editor.putInt(SELECTED_NAV_ITEM_KEY, bottomNavigationView.selectedItemId)
            editor.putBoolean(THEME_PREF_KEY, true)
            editor.apply()
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
            true
        }
        R.id.log_out -> {
            logout()
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

2. 在Activity onCreate中恢复选中状态

override fun onCreate(savedInstanceState: Bundle?) {
    // 先读取主题设置并应用
    val sharedPrefs = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
    val isDarkMode = sharedPrefs.getBoolean(THEME_PREF_KEY, false)
    AppCompatDelegate.setDefaultNightMode(if (isDarkMode) AppCompatDelegate.MODE_NIGHT_YES else AppCompatDelegate.MODE_NIGHT_NO)
    
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottom_nav)
    
    // 恢复之前选中的Bottom Navigation项
    val selectedItemId = sharedPrefs.getInt(SELECTED_NAV_ITEM_KEY, R.id.first_fragment) // 默认第一个Fragment
    bottomNavigationView.selectedItemId = selectedItemId

    // 初始化Bottom Navigation的Fragment切换逻辑
    bottomNavigationView.setOnItemSelectedListener { menuItem ->
        when (menuItem.itemId) {
            R.id.first_fragment -> {
                supportFragmentManager.beginTransaction()
                    .replace(R.id.fragment_container, FirstFragment())
                    .commit()
                true
            }
            R.id.second_fragment -> {
                supportFragmentManager.beginTransaction()
                    .replace(R.id.fragment_container, SecondFragment())
                    .commit()
                true
            }
            // 其他Fragment项...
            else -> false
        }
    }
}

注意事项

  • 确保bottomNavigationView是Activity中对应的控件实例,ID与布局文件一致。
  • 主题设置需在super.onCreate(savedInstanceState)之前调用,保证主题在Activity创建时生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 00:50:06