【问题标题】:How to make the latest chat above others?如何使最新的聊天高于其他人?
【发布时间】:2021-07-17 23:14:15
【问题描述】:

我正在开发一个聊天应用程序,我怎样才能让最新的聊天内容高于其他人?在图片中,收到的最后一条消息是由 Wejdan 发出的,但正如您所见,它仍然在底部,而不是在其他聊天的顶部。

我保存了每条消息及其 timeStamp 和 isSeen 值,如下所示:

我知道它与时间戳有关,但我不知道如何实现它。这是我发送消息的代码:

private void sendMessage (final String sender, final String receiver, String message){
        final String timeStamp = String.valueOf(System.currentTimeMillis());
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("sender", sender);
        hashMap.put("receiver", receiver);
        hashMap.put("message", message);
        hashMap.put("isseen", false);
        hashMap.put("time", timeStamp);
        reference.child("Chats").push().setValue(hashMap);
        final DatabaseReference chatRef = FirebaseDatabase.getInstance().getReference("Chatlist")
                .child(fUser.getUid()).child(userid);
        chatRef.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                if(!snapshot.exists()){
                    chatRef.child("id").setValue(userid);
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError error) {
            }
        });
        final DatabaseReference chatRef1 = FirebaseDatabase.getInstance().getReference("Chatlist")
                .child(receiver).child(fUser.getUid());
        chatRef1.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if(!dataSnapshot.exists())
                {
                    chatRef1.child("id").setValue(fUser.getUid());
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }

        });

此代码用于确定哪些消息未读:

 reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                //fix
                if (!isAdded()) return;
                ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getChildFragmentManager());
                int unread = 0;
                for (DataSnapshot snapshot1 : snapshot.getChildren()){
                    Chat chat = snapshot1.getValue(Chat.class);
                    if(chat.getReceiver().equals(firebaseUser.getUid()) && !chat.isIsseen()){
                        unread++;
                    }
                }
                if(unread == 0 ){
                    viewPagerAdapter.addFragment(new ChatsFragment() , "Chats");
                    
                }else {
                    viewPagerAdapter.addFragment(new ChatsFragment() , "("+unread+") Chats");
             
                }
                viewPagerAdapter.addFragment(new UsersFragment(), "Users");
                viewPager.setAdapter(viewPagerAdapter);
                tabLayout.setupWithViewPager(viewPager);
            }
            @Override
            public void onCancelled(@NonNull DatabaseError error) {
            }
        });

这是我的ChatFragment 的 sn-p(我有所有的聊天记录):

private List<Chatlist> usersList;
    recyclerView.setHasFixedSize(true);
       recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
       recyclerView.hideIfEmpty(recyclerView);
       recyclerView.showIfEmpty(mEmptyView);
       fuser = FirebaseAuth.getInstance().getCurrentUser();
       usersList = new ArrayList<>();
       reference = FirebaseDatabase.getInstance().getReference("Chatlist").child(fuser.getUid());
       reference.addValueEventListener(new ValueEventListener() {
           @Override
           public void onDataChange(@NonNull DataSnapshot snapshot) {
                usersList.clear();
                for(DataSnapshot snapshot1 : snapshot.getChildren()){
                    Chatlist chatlist = snapshot1.getValue(Chatlist.class);
                    usersList.add(chatlist);
                }
                chatList();
           }
           @Override
           public void onCancelled(@NonNull DatabaseError error)
           {
           }
       });
 private void chatList() {
        mUsers = new ArrayList<>();
        reference = FirebaseDatabase.getInstance().getReference("Users");
        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                mUsers.clear();
                for(DataSnapshot snapshot1 : snapshot.getChildren()){
                    User user = snapshot1.getValue(User.class);
                    for(Chatlist chatlist : usersList){
                        if(user.getId().equals(chatlist.getId())){
                            mUsers.add(user);
                        }
                    }
                }
               usersAdapter = new UsersAdapter(getContext(), mUsers , true);
                recyclerView.setAdapter(usersAdapter);
            }
            @Override
            public void onCancelled(@NonNull DatabaseError error) {
            }
        });

请帮忙。

【问题讨论】:

    标签: android


    【解决方案1】:

    您可以通过执行以下操作对来自实时数据库的消息进行排序:

    myRef.orderByChild("timestamp").addChildEventListener(new ChildEventListener{
     /*Note that you need to implement the methods.
       For example: onChildAdded, onChildChanged etc.*/
    })
    

    使用 ChildEventListener 而不是 ValueEventListener,将对引用的每个分支的子项进行排序,例如:

    foo----
          |-branch1---|
          |           |-timestamp: "1234"
          |
          |
          |-branch2---|
                      |-timestamp: "2345"
    

    使用 DatabaseReference myRef = FirebaseDatabase.getInstance().getReference("foo");ChildEventListenerorderByChild(),就像我之前向您展示的那样,查询将对时间戳进行排序!

    如果你的新消息还在底部并且你想交换订单,你可以在你的RecyclerView上使用:

    recyclerView.setStackFromEnd(true)
    reciclerView.setReverseLayout(true)
    

    希望对您有所帮助,祝您编码愉快! :)

    【讨论】:

    • 我不太明白您的回答,您提供的代码中如何按时间排序?我应该在哪里添加这部分?在发送按钮中?
    • 您使用的是 RecyclerView,对吧?好吧,当您使用来自实时数据库服务器的快照填充列表时,您可以使用 orderByChild() 和 onChildEventListener 。还要记住,您不需要引用 DatabaseReference 的孩子,因为它会自动跳过一个孩子,就像我在答案中解释的那样!如果您需要更多帮助,请告诉我。
    • 是的,我正在使用回收视图。好的,我会尝试实现这个,如果它不起作用,我会告诉你
    • 我会在这里帮助以防万一! :)
    • 谢谢你,你真好。我有个问题;这个方法应该在 userAdapter 中还是在 Fragment 本身中实现?你说 orderByChild() 会安排时间,那么还剩下什么?我的意思是即使我将方法本身留空,这也能解决问题吗?
    猜你喜欢
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多