【问题标题】:How to sort chat list according to time of messages?如何根据消息的时间对聊天列表进行排序?
【发布时间】:2021-09-10 09:17:20
【问题描述】:

我正在尝试根据最近的聊天(最新在顶部等)对我的users chat lists 进行排序。 我的chat fragment 看起来像这样:

这是来自chat fragment的sn-p:

 private UsersAdapter usersAdapter;
    private B_RecycleView recyclerView;
    private List<Chatlist> mChatUserList;
    private List<User> mUsers;
    private List<Chat> mChats = new ArrayList<>();
 View view = inflater.inflate(R.layout.fragment_chats, container, false);
       mEmptyView = view.findViewById(R.id.no_chats);
       recyclerView = view.findViewById(R.id.recycle_view);
       recyclerView.setHasFixedSize(true);
       recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
       recyclerView.hideIfEmpty(recyclerView);
       recyclerView.showIfEmpty(mEmptyView);
       fUser = FirebaseAuth.getInstance().getCurrentUser();
       mChatUserList = new ArrayList<>();
       mUsers = new ArrayList<>();
       usersAdapter = new UsersAdapter(getContext(), mUsers , true);
       recyclerView.setAdapter(usersAdapter);
       reference = FirebaseDatabase.getInstance().getReference("Chatlist").child(fUser.getUid());
       reference.addValueEventListener(new ValueEventListener() {
           @Override
           public void onDataChange(@NonNull DataSnapshot snapshot) {
               mChatUserList.clear();
               for(DataSnapshot snapshot1 : snapshot.getChildren()){
                    Chatlist chatlist = snapshot1.getValue(Chatlist.class);
                   mChatUserList.add(chatlist);
                }
               chatList();
           }
           @Override
           public void onCancelled(@NonNull DatabaseError error){
           }
       });

聊天模型类:

public class Chat {
    private String sender;
    private String receiver;
    private String message;
    private String time;
    private String type;
    private boolean isseen;

    public Chat(String sender, String receiver, String message,String time, String type ,boolean isseen){
        this.sender = sender;
        this.receiver = receiver;
        this.message = message;
        this.time = time;
        this.type = type;
        this.isseen =isseen;
    }

我有这样的每条消息的时间戳:

我已经在我的 chatFragment 中尝试过这个:

  private void getChats() {
        reference = FirebaseDatabase.getInstance().getReference("Chats");
        reference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                mChats.clear();
                if (!isAdded()) return;
                for (DataSnapshot snapshot1 : snapshot.getChildren()) {
                    Chat chat = snapshot1.getValue(Chat.class);
                    if(chat.getReceiver().equals(fUser.getUid()) || chat.getSender().equals(fUser.getUid())){
                        mChats.add(chat);
                    }
                }
                sortUsers();
            }

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

    private void sortUsers() {

    Collections.sort(mChats, new ChatTimeComparator());

    if(mChats.size() > 0 && mUsers.size() > 1){
        String lastUserRId = mChats.get(0).getReceiver();
        String lastUserSId = mChats.get(0).getSender();

        int i = 0, selId = 0;
        for(User user: mUsers){
            if(user.getId().equals(lastUserRId) || user.getId().equals(lastUserSId)){
                selId = i;
            }
            i++;
        }

        User user = mUsers.get(selId);
        List<User> tempUsers = new ArrayList<>();
        mUsers.remove(selId);
        tempUsers.addAll(mUsers);
        mUsers.clear();
        mUsers.add(0, user);
        mUsers.addAll(tempUsers);

        usersAdapter.notifyDataSetChanged();
    }
}

public class ChatTimeComparator implements Comparator<Chat>
{
    public int compare(Chat left, Chat right) {
        return right.getTime().compareTo(left.getTime());
    }
}

这仅对最近的聊天进行排序。其余的聊天是随机排序的。 如何对所有聊天进行排序?有什么帮助吗?请注意,我正在尝试对 chatlist 进行排序,而不是消息。

编辑: 根据聊天中发送的最后一条消息,我已经为每个聊天添加了时间,如下所示:

 private void lastMessage(final String userid, final TextView last_msg, final TextView timeSent){
        theLastMessage = "default";
        final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Chats");
        reference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                 for(DataSnapshot snapshot1 : snapshot.getChildren()){
                     Chat chat = snapshot1.getValue(Chat.class);
                     if(chat.getReceiver().equals(firebaseUser.getUid()) && chat.getSender().equals(userid) ||
                             chat.getReceiver().equals(userid) && chat.getSender().equals(firebaseUser.getUid()))
                     {
                         long time = chat.getTime();

                         Calendar calendar = Calendar.getInstance(Locale.getDefault());
                         try {
                             calendar.setTimeInMillis(time);
                         }
                         catch (Exception ex){
                             ex.printStackTrace();
                         }
                         final String pTime = DateFormat.format("hh:mm aa", calendar).toString();
                         timeSent.setText(pTime);
                         if(chat.getType().equals("image")){
                             theLastMessage = "Sent a photo";
                         }
                         else
                         {
                             theLastMessage = chat.getMessage();
                         }
                     }

这是这个 sn-p 的结果:

如您所见,聊天是随机排序的。 那么,现在我可以根据该聊天中发送的最后一条消息的时间对聊天进行排序吗?

【问题讨论】:

    标签: java android firebase-realtime-database


    【解决方案1】:

    我建议不要在客户端重新排序聊天消息,而是让数据库来处理。

    根据您当前的代码/数据,这需要进行以下更改:

    1. 将时间戳存储为数字,而不是字符串。因此,在您的 Chat 类中更改为:private long time;,并在任何地方使用该号码。

    2. 存储倒置的时间戳(也可以作为数字)。 Firebase 实时数据库只能按升序返回结果。您可以在应用程序代码中反转结果,也可以存储反转的时间戳以进行排序。所以invertedTimestamp = -1 * timestamp

    3. 使用查询以正确的顺序获取聊天消息:

       reference = FirebaseDatabase.getInstance().getReference("Chats");
       Query query = reference.orderByChild("invertedTimestamp");
       query.addListenerForSingleValueEvent(new ValueEventListener() {
           ...
      

    【讨论】:

    • 是否可以在不将时间更改为 long 的情况下这样做?因为我到处都在使用它,我担心它会导致很多错误。无论如何,我会尽力给你我的反馈,谢谢
    • 1) 不能保证始终有效。数字的排序方式与字符串不同,时间戳本质上是一个数字。 2)并将其保留为字符串意味着您无论如何都可以存储其反转值。所以:不,对不起。您必须修改代码和数据以修复该数据类型。
    • 我只是想指出聊天项目没有时间戳。正如您从第一张图片中看到的那样。我只有每条消息的时间戳。在这种情况下,您的答案仍然有效吗?
    • 我不确定我理解这意味着什么。您的代码(以及我的答案)仅显示来自 Chats 的加载/订购数据。
    • 啊,我现在明白了:您正在尝试根据用户的最后一条消息对用户的Chatlist 进行排序。这是不可能的,因为您只能对返回的每个子节点正下方的固定位置的数据进行排序。常见的方法是在Chatlist 的每个子节点上添加一个lastMessageTimestamp 属性,并在您编写聊天消息时更新该属性。例如:stackoverflow.com/questions/44535831/…stackoverflow.com/q/41704506
    猜你喜欢
    • 2021-02-27
    • 2021-03-06
    • 2020-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    相关资源
    最近更新 更多