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
相关产品推荐
相关产品推荐

