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

Android RecyclerView中按日期(最新到最旧)排序Firebase数据库用户帖子的问题

Android RecyclerView中按日期(最新到最旧)排序Firebase数据库用户帖子的问题

嘿,我看了你的代码和问题描述,现在的问题核心是Firebase返回的数据本身没有按时间排序,所以你用RecyclerView的ReverseLayout自然没法得到正确的顺序。接下来我给你两种可行的解决方案,从根源上解决排序问题:

方案一:用时间戳存储(推荐,最准确高效)

这种方法是把帖子的发布时间以时间戳(long类型,比如System.currentTimeMillis())的形式存在Firebase里,这样不管是Firebase查询排序还是本地排序都非常方便。

步骤1:修改CustomUserData类

添加时间戳字段和对应的getter/setter:

public class CustomUserData implements Serializable {
    // 原有字段...
    private long timestamp; // 新增时间戳字段

    // 空构造函数保留
    public CustomUserData() {}

    // 带时间戳的构造函数
    public CustomUserData(String address, String division, String contact, String name, String bloodGroup, String time, String date, long timestamp) {
        Address = address;
        Division = division;
        Contact = contact;
        Name = name;
        BloodGroup = bloodGroup;
        Time = time;
        Date = date;
        this.timestamp = timestamp; // 赋值时间戳
    }

    // 新增getter和setter
    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    // 原有getter/setter...
}

步骤2:发布帖子时存入时间戳

用户发布帖子的时候,生成当前时间戳并传入CustomUserData对象:

// 发布帖子的代码里
long postTimestamp = System.currentTimeMillis();
CustomUserData newPost = new CustomUserData(address, division, contact, name, bloodGroup, time, date, postTimestamp);
// 然后把newPost存入Firebase的posts节点

步骤3:修改Firebase查询并排序

在HomeView的AddPosts()方法里,修改Query让Firebase按时间戳排序返回数据,然后本地反转得到最新到最旧的顺序:

private void AddPosts() {
    // 按timestamp升序查询(旧帖子在前,新帖子在后)
    Query allposts = donor_ref.child("posts").orderByChild("timestamp");
    
    pd.show();
    allposts.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            postLists.clear(); // 先清空旧数据,避免重复
            if(dataSnapshot.exists()) {
                for (DataSnapshot singlepost : dataSnapshot.getChildren()) {
                    CustomUserData customUserData = singlepost.getValue(CustomUserData.class);
                    postLists.add(customUserData);
                }
                // 反转列表,变成最新帖子在前
                Collections.reverse(postLists);
                restAdapter.notifyDataSetChanged();
            } else {
                Toast.makeText(getActivity(), "No Blood Request Found!", Toast.LENGTH_LONG).show();
            }
            pd.dismiss();
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            Log.d("User", databaseError.getMessage());
            pd.dismiss();
        }
    });
}

步骤4:去掉RecyclerView的反转设置

现在数据已经是正确顺序了,不需要再用ReverseLayout:

// 注释掉这两行代码
// mLayoutManager.setReverseLayout(true);
// mLayoutManager.setStackFromEnd(true);

方案二:基于现有日期时间字段本地排序(不用改存储)

如果你暂时不想修改Firebase的存储格式,可以在获取所有数据后,用Comparator对列表进行排序:

修改AddPosts()方法的onDataChange部分

@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
    postLists.clear();
    if(dataSnapshot.exists()) {
        for (DataSnapshot singlepost : dataSnapshot.getChildren()) {
            CustomUserData customUserData = singlepost.getValue(CustomUserData.class);
            postLists.add(customUserData);
        }
        // 按日期时间降序排序
        Collections.sort(postLists, new Comparator<CustomUserData>() {
            @Override
            public int compare(CustomUserData o1, CustomUserData o2) {
                // 把日期和时间拼接成完整字符串,转换成Date对象比较
                SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss", Locale.getDefault());
                try {
                    Date postTime1 = sdf.parse(o1.getDate() + " " + o1.getTime());
                    Date postTime2 = sdf.parse(o2.getDate() + " " + o2.getTime());
                    // 降序排列,所以用o2和o1比较
                    return postTime2.compareTo(postTime1);
                } catch (ParseException e) {
                    e.printStackTrace();
                    return 0;
                }
            }
        });
        restAdapter.notifyDataSetChanged();
    } else {
        Toast.makeText(getActivity(), "No Blood Request Found!", Toast.LENGTH_LONG).show();
    }
    pd.dismiss();
}

同样,记得去掉RecyclerView的ReverseLayout设置。

额外优化建议

  • 你原来在循环里每次add数据都调用restAdapter.notifyDataSetChanged(),这样效率很低,应该等所有数据都添加完再调用一次就好。
  • 每次加载数据前清空postLists,避免重复数据叠加。

备注:内容来源于stack exchange,提问作者Safiyulla Mona

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 03:34:32