Android设备旋转时RecyclerView重复加载问题求助
看起来你遇到的核心问题是横竖屏切换时,Activity重建导致重复添加Fragment,从而RecyclerView出现重复显示。每次旋转屏幕,系统会销毁并重新创建你的RecipeStepsActivity,而你在onCreate方法里每次都会执行add操作添加新的RecipeStepsFragment,旧的Fragment实例并没有被移除,最终多个Fragment叠加显示,就出现了RecyclerView重复加载的情况。
下面是具体的解决方案:
1. 避免重复添加Fragment(最根本的解决方法)
在Activity的onCreate方法中,先判断savedInstanceState是否为null。当屏幕旋转重建时,savedInstanceState不为null,此时FragmentManager会自动恢复之前的Fragment实例,不需要再创建新的Fragment并添加。
修改你的RecipeStepsActivity代码:
public class RecipeStepsActivity extends AppCompatActivity { static Recipe recipe; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_recipe_steps); if (StepDetailActivity.SDA_TAG.equals(StepDetailActivity.NEGATIVE)) recipe = getIntent().getParcelableExtra("recipe"); ActionBar ab = getSupportActionBar(); if (ab != null) ab.setTitle(recipe.getName()); // 仅在首次创建Activity时添加Fragment if (savedInstanceState == null) { Bundle b = new Bundle(); b.putParcelable("recipe", recipe); RecipeStepsFragment recipeStepsFragment = new RecipeStepsFragment(); recipeStepsFragment.setArguments(b); FragmentManager fm = getSupportFragmentManager(); fm.beginTransaction() .add(R.id.frame_layout_steps, recipeStepsFragment) .commit(); } } }
2. 优化RecyclerView滚动位置的保存与恢复
你当前保存滚动位置的方式recyclerView.getVerticalScrollbarPosition()并不准确,建议使用LayoutManager的方法来获取和恢复滚动位置:
修改RecipeStepsFragment的相关代码:
保存滚动位置
@Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); if (layoutManager != null) { // 获取当前可见的第一个item的位置 outState.putInt("position", layoutManager.findFirstVisibleItemPosition()); } }
恢复滚动位置
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); ButterKnife.bind(this, view); // ... 其他原有代码 ... if(savedInstanceState != null){ int scrollPosition = savedInstanceState.getInt("position"); // 使用post确保RecyclerView已经初始化完成再滚动 recyclerView.post(() -> { LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); if (layoutManager != null) { layoutManager.scrollToPosition(scrollPosition); } }); } }
3. 可选:禁止Activity横竖屏重建(不推荐长期使用)
如果你想快速临时解决问题,可以在AndroidManifest.xml中给RecipeStepsActivity添加配置,让系统在横竖屏切换时不销毁重建Activity:
<activity android:name=".RecipeStepsActivity" android:configChanges="orientation|screenSize"> </activity>
这种方式虽然简单,但会跳过系统的状态恢复机制,当有其他配置变化(比如字体大小调整)时可能出现问题,所以优先推荐第一种方案。
内容的提问来源于stack exchange,提问作者Erayzer

