切换夜间模式时RecyclerView列表项重复问题如何解决
问题原因
调用AppCompatDelegate.setDefaultNightMode()修改暗黑模式时,系统会默认触发应用栈内所有Activity的销毁重建流程。如果你的MainActivity在onCreate方法中没有做状态判断,每次创建都往RecyclerView的数据源中新增数据,重建时就会出现列表条目重复的问题。
解决方案
方案1:修改数据加载逻辑(推荐)
在加载列表数据前判断当前Activity是否是首次创建,只有首次创建时才加载数据,重建时复用原有数据即可:
@Override protected void onCreate(Bundle savedInstanceState) { // 原有暗黑模式配置逻辑保持不变,注意必须放在super.onCreate之前 PreferenceManager.setDefaultValues(this, R.xml.preferences, false); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); boolean isDarkMode = sharedPref.getBoolean(getString(R.string.key_dark_mode), false); AppCompatDelegate.setDefaultNightMode(isDarkMode ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化RecyclerView RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); if (mAdapter == null) { mAdapter = new MyListAdapter(); recyclerView.setAdapter(mAdapter); } // 仅首次创建Activity时加载数据,重建时不重复加载 if (savedInstanceState == null) { // 你的原有列表数据加载逻辑 List<DataBean> dataList = loadDataFromLocalOrNetwork(); mAdapter.setData(dataList); } }
额外优化:你当前SwitchPreference的OnPreferenceChangeListener中不需要手动存储偏好值,SwitchPreference默认会自动将选中状态同步到SharedPreferences,可直接删除手动putBoolean的冗余代码。
方案2:禁止Activity重建
如果不需要系统默认的重建刷新逻辑,可以在AndroidManifest.xml中给对应Activity添加configChanges配置,自行处理暗黑模式变更:
<activity android:name=".MainActivity" android:configChanges="uiMode|orientation|screenSize" /> <activity android:name=".SettingsActivity" android:configChanges="uiMode|orientation|screenSize" />
添加配置后切换暗黑模式不会触发Activity重建,也就不会出现数据重复加载的问题。如果需要手动适配主题,可以重写onConfigurationChanged方法更新UI即可。
内容的提问来源于stack exchange,提问作者sanoj lawrence
相关产品推荐
相关产品推荐

