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

如何按时间排序聊天APP首页RecyclerView的最近会话项?

实现会话按最后消息时间置顶的解决方案

要解决这个问题,核心是把用户信息和对应会话的最后消息时间绑定在一起,再基于时间排序。以下是具体实现步骤:

1. 创建会话包装类

新建ChatSession类,封装用户信息和对应会话的最后消息时间,为排序提供依据:

public class ChatSession {
    private User user;
    private long lastMsgTime;

    public ChatSession(User user, long lastMsgTime) {
        this.user = user;
        this.lastMsgTime = lastMsgTime;
    }

    // Getter和Setter方法
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public long getLastMsgTime() {
        return lastMsgTime;
    }

    public void setLastMsgTime(long lastMsgTime) {
        this.lastMsgTime = lastMsgTime;
    }
}

2. 修改HomeActivity的数据结构与查询逻辑

把原有的ArrayList<User>替换为ArrayList<ChatSession>,调整Firebase查询流程,先获取好友列表,再逐个查询每个好友的会话最后消息时间:

// 替换原有的users列表
ArrayList<ChatSession> chatSessions; 

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ActivityHomeBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());

    chatSessions = new ArrayList<>();
    homeAdapter = new HomeAdapter(this, chatSessions);
    binding.homeRecyclerView.setAdapter(homeAdapter);

    FirebaseAuth mAuth = FirebaseAuth.getInstance();
    FirebaseDatabase database = FirebaseDatabase.getInstance();
    String currentUserId = mAuth.getUid();

    // 先获取当前用户的好友ID列表
    database.getReference().child("users").child(currentUserId).child("friendList")
            .addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot friendSnapshot) {
                    chatSessions.clear();
                    // 遍历每个好友ID
                    for (DataSnapshot friendIdSnapshot : friendSnapshot.getChildren()) {
                        String friendId = friendIdSnapshot.getValue(String.class);
                        if (friendId == null) continue;

                        // 获取好友的User信息
                        database.getReference().child("users").child(friendId)
                                .addListenerForSingleValueEvent(new ValueEventListener() {
                                    @Override
                                    public void onDataChange(@NonNull DataSnapshot userSnapshot) {
                                        User user = userSnapshot.getValue(User.class);
                                        if (user == null) return;

                                        // 构造会话房间ID
                                        String senderRoom = currentUserId + user.getUserId();
                                        // 获取该会话的最后消息时间
                                        database.getReference().child("chats").child(senderRoom)
                                                .addListenerForSingleValueEvent(new ValueEventListener() {
                                                    @Override
                                                    public void onDataChange(@NonNull DataSnapshot chatSnapshot) {
                                                        long lastMsgTime = 0;
                                                        if (chatSnapshot.exists()) {
                                                            Long tempTime = chatSnapshot.child("lastMsgTime").getValue(Long.class);
                                                            lastMsgTime = tempTime == null ? 0 : tempTime;
                                                        }
                                                        // 添加到会话列表
                                                        chatSessions.add(new ChatSession(user, lastMsgTime));
                                                        // 排序:按最后消息时间降序,最新会话置顶
                                                        Collections.sort(chatSessions, (cs1, cs2) -> 
                                                            Long.compare(cs2.getLastMsgTime(), cs1.getLastMsgTime())
                                                        );
                                                        homeAdapter.notifyDataSetChanged();
                                                        progressDialog.dismiss();
                                                    }

                                                    @Override
                                                    public void onCancelled(@NonNull DatabaseError error) {}
                                                });
                                    }

                                    @Override
                                    public void onCancelled(@NonNull DatabaseError error) {}
                                });
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError error) {}
            });
}

3. 修改HomeAdapter适配ChatSession

将适配器改为接收ArrayList<ChatSession>,从包装类中获取用户信息进行展示:

public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.HomeViewHolder> {

    FirebaseAuth mAuth;
    FirebaseDatabase database;
    Context context;
    ArrayList<ChatSession> chatSessions; // 替换原有的users列表

    public HomeAdapter(Context context, ArrayList<ChatSession> chatSessions) {
        this.context = context;
        this.chatSessions = chatSessions;
    }

    @NonNull
    @Override
    public HomeViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.activity_home_item, parent, false);
        return new HomeViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull HomeViewHolder holder, int position) {
        ChatSession chatSession = chatSessions.get(position);
        User user = chatSession.getUser();
        mAuth = FirebaseAuth.getInstance();
        database = FirebaseDatabase.getInstance();

        String senderId = mAuth.getUid();
        String senderRoom = senderId + user.getUserId();

        holder.binding.friendName.setText(user.getName());
        Picasso.get().load(user.getProfileImage()).into(holder.binding.friendProfilePic);
        holder.binding.friend.setOnClickListener(v -> {
            Intent intent = new Intent(context, ChattingActivity.class);
            intent.putExtra("userName", user.getName());
            intent.putExtra("profilePic", user.getProfileImage());
            intent.putExtra("userId", user.getUserId());
            intent.putExtra("token", user.getToken());
            context.startActivity(intent);
        });

        // 保持原有消息监听逻辑,实时更新最后消息内容与时间
        database.getReference().child("chats").child(senderRoom)
                .addValueEventListener(new ValueEventListener() {
                    @SuppressLint("SetTextI18n")
                    @Override
                    public void onDataChange(@NonNull DataSnapshot snapshot) {
                        if (snapshot.exists()) {
                            String lastMsg = snapshot.child("lastMsg").getValue(String.class);
                            Long time = snapshot.child("lastMsgTime").getValue(Long.class);
                            if (time == null) time = 0L;
                            @SuppressLint("SimpleDateFormat")
                            SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm a");

                            holder.binding.friendLastMsg.setText(lastMsg);
                            holder.binding.friendLastMsgTime.setText(dateFormat.format(new Date(time)));
                        } else {
                            holder.binding.friendLastMsg.setText("Tap to chat");
                            holder.binding.friendLastMsgTime.setText("");
                        }
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError error) {}
                });
    }

    @Override
    public int getItemCount() {
        return chatSessions.size();
    }

    protected static class HomeViewHolder extends RecyclerView.ViewHolder {
        ActivityHomeItemBinding binding;
        public HomeViewHolder(@NonNull View view) {
            super(view);
            binding = ActivityHomeItemBinding.bind(view);
        }
    }
}

4. 优化说明

  • 使用addListenerForSingleValueEvent替代addValueEventListener,避免重复监听导致的性能问题与数据重复添加
  • 包装类ChatSession实现了用户信息与会话时间的绑定,解决了User类无时间字段的排序难题
  • 排序逻辑采用降序,确保最新消息的会话始终排在列表顶部
  • 处理了时间字段为空的边界情况,默认设为0,让无会话的好友排在列表末尾

内容的提问来源于stack exchange,提问作者Topu Rayhan Rabby Mamud

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:54:30