You need to enable JavaScript to run this app. RecyclerView加载更多数据时仅显示新项不保留旧项问题求助
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 05:15:02