RecyclerView加载更多数据时仅显示新项不保留旧项问题求助
问题原因
- 每次拿到新分页数据后直接替换了适配器中的原有列表,没有做数据追加操作
onChanged回调中重复调用setAdapter属于冗余操作,会导致RecyclerView重新渲染整个列表,不仅影响性能,还可能出现滚动位置复位的问题- 适配器的
setData方法是直接覆盖全局数据列表,不是在原有列表基础上新增数据 - 没有在Fragment中维护全量的数据列表,每次接口请求返回的仅为当前页的10条数据,直接传递给适配器就会覆盖旧数据
修复步骤
1. 修改RecyclerViewAdapter,新增追加数据的方法
修复原有构造方法的空指针隐患,同时区分全量替换和追加两种数据更新场景:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { Activity context; // 初始化时直接创建空列表,避免空指针 private ArrayList<User> userArrayList = new ArrayList<>(); public RecyclerViewAdapter(Activity context) { this.context = context; } // 首次加载、下拉刷新场景使用,全量替换数据 public void setData(ArrayList<User> userArrayListOne){ userArrayList.clear(); userArrayList.addAll(userArrayListOne); notifyDataSetChanged(); System.out.println("%% %% 全量数据更新完成 %% %%"); } // 加载更多场景使用,追加新数据 public void addData(ArrayList<User> newUserList){ int oldSize = userArrayList.size(); userArrayList.addAll(newUserList); // 用局部刷新代替全量刷新,性能更优 notifyItemRangeInserted(oldSize, newUserList.size()); System.out.println("%% %% 追加数据完成 %% %%"); } // 剩余原有代码保持不变即可 @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { System.out.println("************ onCreateViewHolder ***********"); View rootView = LayoutInflater.from(context).inflate(R.layout.item,parent,false); return new RecyclerViewViewHolder(rootView); } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { System.out.println("************ onBindViewHolder ***********"); User user = userArrayList.get(position); RecyclerViewViewHolder viewHolder= (RecyclerViewViewHolder) holder; // Set title as HTML code on view if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { viewHolder.txtView_title.setText(Html.fromHtml(user.getTitle(), Html.FROM_HTML_MODE_COMPACT)); } else { viewHolder.txtView_title.setText(Html.fromHtml(user.getTitle())); } viewHolder.txtView_description.setText(user.getDescription()); Glide.with(context).load(user.getImagePath()).centerInside().error(R.drawable.yahushuas_commands_pt__2).into(viewHolder.imgView_icon); } @Override public int getItemCount() { return userArrayList.size(); } class RecyclerViewViewHolder extends RecyclerView.ViewHolder { ImageView imgView_icon; TextView txtView_title; TextView txtView_description; public RecyclerViewViewHolder(@NonNull ViewItemView) { super(itemView); imgView_icon = itemView.findViewById(R.id.imgView_icon); txtView_title = itemView.findViewById(R.id.txtView_title); txtView_description = itemView.findViewById(R.id.txtView_description); } } }
2. 修改Fragment逻辑,删除冗余操作,维护全量数据
新增全量数据列表变量,区分首次加载和加载更多的逻辑,删除重复设置适配器的操作:
public class twoFragment extends Fragment implements LifecycleOwner { private twoViewModel twoViewModel; private RecyclerView recyclerView; private RecyclerViewAdapter recyclerViewAdapter; private EndlessRecyclerViewScrollListener scrollListener; WebRequest webRequest = new WebRequest(); // 维护全量数据列表 private ArrayList<User> allUserList = new ArrayList<>(); public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { System.out.println("************ onCreateView ***********"); System.out.println("************ ViewModelProvider ***********"); twoViewModel = new ViewModelProvider(this).get(twoViewModel.class); View root = inflater.inflate(R.layout.two, container, false); recyclerView = root.findViewById(R.id.rv_main); recyclerView.setHasFixedSize(true); recyclerViewAdapter = new RecyclerViewAdapter(requireActivity()); final int columns = getResources().getInteger(R.integer.gallery_columns); GridLayoutManager gridLayoutManager = new GridLayoutManager(requireActivity(), columns); recyclerView.setLayoutManager(gridLayoutManager); // 初始化时仅设置一次适配器即可,不需要重复设置 recyclerView.setAdapter(recyclerViewAdapter); // Endless scrolling scrollListener = new EndlessRecyclerViewScrollListener(gridLayoutManager) { @Override public void onLoadMore(int page, int totalItemsCount, RecyclerView view) { System.out.println("************ onLoadMore >>> EndlessRecyclerViewScrollListener ***********"); System.out.println("************ onLoadMore >>> page ***********" + page); webRequest.MakeRequest("BROWSE_REQUEST", page +1, "", twoViewModel.getUserMutableLiveData()); } }; recyclerView.addOnScrollListener(scrollListener); twoViewModel.getUserMutableLiveData().observe(getViewLifecycleOwner(),userListUpdateObserver); return root; }; private Observer<ArrayList<User>> userListUpdateObserver = new Observer<ArrayList<User>>() { @Override public void onChanged(ArrayList<User> userArrayList) { System.out.println("************ onChanged ***********"); if (allUserList.isEmpty()) { // 首次加载,全量替换数据 allUserList.addAll(userArrayList); recyclerViewAdapter.setData(allUserList); } else { // 加载更多,追加新数据 allUserList.addAll(userArrayList); recyclerViewAdapter.addData(userArrayList); } } }; }
3. 补充优化
如果后续接入下拉刷新功能,刷新时先清空allUserList,再请求第一页数据即可。
内容的提问来源于stack exchange,提问作者sundrycode
相关产品推荐
相关产品推荐

