You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何RecyclerView总是出现重复列表?使用LiveData时的问题求助

问题排查与修复方案

核心问题分析

  • 重复项产生原因:datesWithDupes、datesWithoutDupes、paymentByDateList这些集合没在每次数据更新时清空,每次onChanged触发都会追加旧数据;同时每次刷新都给同一个日期重复注册Observer,导致同一日期的支付数据被多次添加到列表。
  • 列表顺序随机原因:datesWithoutDupes仅通过遍历去重,没做排序处理,且原始payments列表顺序可能不稳定,最终导致展示顺序随机。

修复步骤与代码修改

  1. 清空集合避免重复:每次onChanged触发时,先清空所有临时存储和最终展示的集合,确保数据计算是全新的。
  2. 移除重复Observer注册:不再循环注册getPaymentsByDate的Observer,直接在内存中对getAllPayments返回的列表按日期分组,避免重复监听。
  3. 对日期排序:去重后给日期列表排序,保证展示顺序稳定。

修改后的代码示例:

adapter = new PaymentsByDateParentAdapter(getContext());
recyclerView.setAdapter(adapter);

viewModel = new ViewModelProvider(this).get(SchoolViewModel.class);

viewModel.getAllPayments().observe(getViewLifecycleOwner(), new Observer<List<Payment>>() {
    @Override
    public void onChanged(List<Payment> payments) {
        // 清空所有集合,避免旧数据残留
        datesWithDupes.clear();
        datesWithoutDupes.clear();
        paymentByDateList.clear();

        // 提取日期并去重
        for (Payment payment : payments) {
            String date = payment.getPaymentDate();
            if (!datesWithoutDupes.contains(date)) {
                datesWithoutDupes.add(date);
            }
        }

        // 对日期排序,保证展示顺序固定
        Collections.sort(datesWithoutDupes);

        // 内存中按日期分组,避免多次查询
        Map<String, List<Payment>> dateGroupMap = new HashMap<>();
        for (Payment payment : payments) {
            String date = payment.getPaymentDate();
            dateGroupMap.computeIfAbsent(date, k -> new ArrayList<>()).add(payment);
        }

        // 构建最终展示列表
        for (String date : datesWithoutDupes) {
            List<Payment> datePayments = dateGroupMap.getOrDefault(date, new ArrayList<>());
            PaymentByDate paymentByDate = new PaymentByDate(date, datePayments);
            paymentByDateList.add(paymentByDate);
        }

        // 更新适配器数据
        adapter.setPayments(paymentByDateList);
    }
});

额外优化建议

  • 把按日期分组、排序的逻辑移到ViewModel层处理,让View层只负责展示,更符合MVVM架构的职责划分。
  • 如果getPaymentsByDate是数据库查询方法,内存分组比多次查询数据库效率更高,也能避免重复数据问题。

内容的提问来源于stack exchange,提问作者user18222209

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:50:21