Fragment中RecyclerView项在设备唤醒后重叠问题求助
解决RecyclerView休眠唤醒后条目重叠的问题
兄弟,我之前也踩过这个RecyclerView重叠的坑!结合你描述的情况,大概率是设备休眠唤醒时Activity/Fragment重建导致的重复加载,给你几个针对性的解决方案:
1. 检查Fragment的添加方式,避免重复实例化
当Activity重建时,如果你的代码是在onCreate里直接addFragment而没有判断是否已经存在,就会导致多个Fragment实例叠加,自然RecyclerView就会出现两层。
解决方法:在添加Fragment前先检查是否已存在:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 关键:判断savedInstanceState是否为空,避免重建时重复添加Fragment if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.container, YourFragment.newInstance()) .commit(); } }
2. 避免在Fragment的生命周期中重复加载数据/初始化Adapter
如果你的Fragment每次在onCreateView或者onViewCreated里都重新创建Adapter并添加数据,而没有判断数据是否已经存在,唤醒重建后就会把数据再塞一遍,导致列表重复。
解决方法:
- 把Adapter和数据列表作为Fragment的成员变量,初始化前先判断是否已存在:
public class YourFragment extends Fragment { private RecyclerView mRecyclerView; private YourAdapter mAdapter; private List<YourData> mDataList = new ArrayList<>(); @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_your, container, false); mRecyclerView = view.findViewById(R.id.recycler_view); // 只有当Adapter未初始化时才创建 if (mAdapter == null) { mAdapter = new YourAdapter(mDataList); mRecyclerView.setAdapter(mAdapter); mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); // 加载数据的方法,只在首次执行 loadData(); } return view; } private void loadData() { // 这里是你的数据加载逻辑,比如从网络/本地获取 // 注意:加载前先清空列表!避免重复添加 mDataList.clear(); mDataList.addAll(yourDataSource); mAdapter.notifyDataSetChanged(); } }
- 另外,也可以利用
onSaveInstanceState保存数据,重建时恢复,避免重复请求:
@Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); // 保存数据列表(如果是可序列化的对象) outState.putSerializable("data_list", (Serializable) mDataList); } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { // 恢复之前保存的数据 mDataList = (List<YourData>) savedInstanceState.getSerializable("data_list"); } }
3. 配置Activity的configChanges(可选)
如果你的界面不需要在屏幕状态变化时重建,可以在Manifest里给Activity添加android:configChanges属性,减少不必要的重建:
<activity android:name=".YourActivity" android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|uiMode"> </activity>
不过这个方法是“治标不治本”,更推荐前面两种从根源解决的方式。
4. 清理RecyclerView引用,防止残留
可以在Fragment的onDestroyView里清空RecyclerView的引用,避免内存泄漏的同时也防止残留视图:
@Override public void onDestroyView() { super.onDestroyView(); mRecyclerView.setAdapter(null); mRecyclerView = null; }
你可以先试试第一种方法,检查Activity里添加Fragment的逻辑,这是最常见的触发原因!
内容的提问来源于stack exchange,提问作者shubham gupta
相关产品推荐
相关产品推荐

