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

RecyclerView按日期排序遇空指针异常,notifyDataSetChanged()报错

解决RecyclerView排序时的空指针异常与更新问题

首先来说你遇到的两个核心问题:空指针异常和RecyclerView不更新,我们逐个拆解解决:

一、空指针异常的根源

你在onCreate里直接调用adapter.notifyDataSetChanged()时,adapter对象还没完成初始化!因为adapter是在showPendingTraject()方法里创建的,而showPendingTraject()依赖GetAllTrajects()调用——如果GetAllTrajects()是异步操作(比如从数据库/网络加载数据),那onCreate执行到notify代码时,showPendingTraject()还没来得及执行,adapter还是null,自然会抛出空指针。

哪怕GetAllTrajects()是同步的,当前代码的执行顺序也可能导致问题:你先调用GetAllTrajects(),紧接着就排序并notify,但如果showPendingTraject()在GetAllTrajects()内部的逻辑没走完,adapter依然没被赋值。最稳妥的方式是提前初始化Adapter,从根源避免它为null。

二、分步解决方案

1. 提前初始化Adapter,杜绝空指针

在onCreate的初始化阶段,就创建Adapter并绑定到RecyclerView,哪怕此时列表是空的:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_pending_traject_recycler_view);
    listPendingTraject=new ArrayList<>();
    recyclerPendingTraject = (RecyclerView)findViewById(R.id.pendingTrajectRecyclerView);
    recyclerPendingTraject.setLayoutManager(new LinearLayoutManager(this));
    
    // 提前初始化Adapter,传入空列表占位
    adapter = new AdapterPendingTraject(listPendingTraject);
    recyclerPendingTraject.setAdapter(adapter);
    
    GetAllTrajects();
}

2. 确保数据加载完成后再排序+更新

情况1:GetAllTrajects()是同步加载数据

直接在GetAllTrajects()执行完成后(数据已经添加到列表),执行排序和notify操作:

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ... 前面的初始化代码 ...
    
    GetAllTrajects();
    
    // 数据已加载,开始排序
    Collections.sort(listPendingTraject, new Comparator<PendingTrajectPOJO>() {
        @Override
        public int compare(PendingTrajectPOJO a, PendingTrajectPOJO b) {
            SimpleDateFormat formatDate = new SimpleDateFormat("dd/MMM/yyyy");
            try {
                Date dateA = formatDate.parse(a.getDate());
                Date dateB = formatDate.parse(b.getDate());
                // 按日期升序排列(旧日期在前),要降序就返回 dateB.compareTo(dateA)
                return dateA.compareTo(dateB);
            } catch (ParseException e) {
                e.printStackTrace();
                // 解析失败时,按原字符串排序,避免排序逻辑崩溃
                return a.getDate().compareTo(b.getDate());
            }
        }
    });
    
    // 此时Adapter已初始化,不会触发空指针
    adapter.notifyDataSetChanged();
}

情况2:GetAllTrajects()是异步加载数据(如网络请求、AsyncTask)

需要在数据加载完成的回调环节执行排序和notify,比如把逻辑放到showPendingTraject()的末尾:

private void showPendingTraject() {
    listPendingTraject.add(new PendingTrajectPOJO(nameUsers,coordenatesOriginBundle,Origin,Destination,DataIHora,coordenatesDestiBundle,contadorCordenades));
    Log.d("ID",""+nomUser);
    
    // 对已加载的数据排序
    Collections.sort(listPendingTraject, new Comparator<PendingTrajectPOJO>() {
        @Override
        public int compare(PendingTrajectPOJO a, PendingTrajectPOJO b) {
            SimpleDateFormat formatDate = new SimpleDateFormat("dd/MMM/yyyy");
            try {
                Date dateA = formatDate.parse(a.getDate());
                Date dateB = formatDate.parse(b.getDate());
                return dateA.compareTo(dateB);
            } catch (ParseException e) {
                e.printStackTrace();
                return a.getDate().compareTo(b.getDate());
            }
        }
    });
    
    // 通知Adapter更新UI
    adapter.notifyDataSetChanged();
}

3. 修正排序逻辑的bug

你原来的compare方法存在逻辑缺陷:return date.before(date1)?1:0;

  • 当date早于date1时返回1,会让排序变成降序,但如果date晚于date1或两者相等,都返回0,这会导致大量元素的排序位置不正确,结果不稳定。
  • 正确做法是使用Date类的compareTo()方法,它会返回-1、0、1三个符合Comparator规范的结果,保证排序逻辑正确。

三、额外优化建议

如果你的Adapter是自定义的,建议在Adapter内部添加一个更新数据的方法,让代码更规范:

public class AdapterPendingTraject extends RecyclerView.Adapter<...> {
    private List<PendingTrajectPOJO> mDataList;
    
    public AdapterPendingTraject(List<PendingTrajectPOJO> dataList) {
        mDataList = dataList;
    }
    
    // 对外提供的更新列表方法
    public void updateData(List<PendingTrajectPOJO> newData) {
        mDataList.clear();
        mDataList.addAll(newData);
        notifyDataSetChanged();
    }
}

之后排序完成后,直接调用adapter.updateData(listPendingTraject)即可完成UI更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:36:02