简体   繁体   English

每次发送或接收消息时,如何使最后联系的用户出现在 recyclerview 的列表顶部?

[英]How can I make last contacted user appear on top of list in recyclerview each time a message is sent or received?

I am building a Chat application using Firebase database.我正在使用 Firebase 数据库构建一个聊天应用程序。 I have been able send and receive chats, I have also been able to get the users contacted under java class ChatsActivty The problem is that the users in my ChatsActivity are only ordered alphabetically even when a new message is sent or received ie onDataChange, the list remains the same.我已经能够发送和接收聊天,我还能够在 java class ChatsActivty 下联系到用户问题是我的 ChatsActivity 中的用户即使在发送或接收新消息时也仅按字母顺序排序,即 onDataChange,列表保持不变。 I want user latest contacted to appear on top every time a message is sent or received.我希望每次发送或接收消息时,最近联系的用户都会出现在顶部。

My code is as shown below:我的代码如下所示:

ChatsActivity.java ChatsActivity.java

public class ChatsActivity extends AppCompatActivity {

    private RecyclerView chatsRecyclerview;

    private AdapterUsers userAdapter;
    private List<ModelUser> mUsers;

    FirebaseUser fUser;
    DatabaseReference reference;

    private List<String> userList;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chats);

        ActionBar actionBar = getSupportActionBar();
        actionBar.setTitle("Messages");
        actionBar.setDisplayHomeAsUpEnabled(true);

        chatsRecyclerview = findViewById(R.id.chats_recyclerview);

        //Linear Layout for RecyclerView
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(ChatsActivity.this);
        //recyclerview properties

        chatsRecyclerview.setHasFixedSize(true);
        chatsRecyclerview.setLayoutManager(linearLayoutManager);

        fUser = FirebaseAuth.getInstance().getCurrentUser();
        userList = new ArrayList<>();

        reference = FirebaseDatabase.getInstance().getReference("Chats");
        Query query = reference.orderByKey().limitToLast(10000);
        query.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                userList.clear();

                for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                    ModelChat chat = dataSnapshot.getValue(ModelChat.class);

                    if (chat.getSender().equals(fUser.getUid())) {
                        userList.add(chat.getReceiver());
                    }
                    if (chat.getReceiver().equals(fUser.getUid())) {
                        userList.add(chat.getSender());
                    }
                }
                readChats();
            }

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

            }
        });

    }

    private void readChats() {
        mUsers = new ArrayList<>();
        reference = FirebaseDatabase.getInstance().getReference("Users");

        reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                mUsers.clear();

                for (DataSnapshot ds : snapshot.getChildren()) {
                    ModelUser user = ds.getValue(ModelUser.class);

                    for (String uid : userList) {
                        assert user != null;
                        if (user.getUid().equals(uid)) {
                            mUsers.add(user);
                            break;
                        }
                    }

                }
                userAdapter = new AdapterUsers(ChatsActivity.this, mUsers);
                chatsRecyclerview.setAdapter(userAdapter);
            }

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

            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            startActivity(new Intent(ChatsActivity.this, HomeActivity.class));
            ChatsActivity.this.finish();
        }

        return super.onOptionsItemSelected(item);
    }

}

My AdapterUsers code:我的 AdapterUsers 代码:

public class AdapterUsers extends RecyclerView.Adapter<AdapterUsers.MyHolder>{公共 class AdapterUsers 扩展 RecyclerView.Adapter<AdapterUsers.MyHolder>{

Context context;
List<ModelUser> userList;

//Constructor > Generate
public AdapterUsers(Context context, List<ModelUser> userList) {
    this.context = context;
    this.userList = userList;
}

@NonNull
@Override
public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    //Inflate layout (row_user)
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_users, parent, false);

    return new MyHolder(view);
}

@Override
public void onBindViewHolder(@NonNull MyHolder holder, int position) {
    //get data
    String userUID = userList.get(position).getUid();
    String userProfilePic = userList.get(position).getProfilepic();
    String userName = userList.get(position).getFirstname() + " " + userList.get(position).getLastname();
    String userNickname = userList.get(position).getNickname();
    String userStatus = userList.get(position).getStatus();

    //set data
    holder.mNameTv.setText(userName);
    holder.mNicknameTv.setText(userNickname);
    holder.mStatusTv.setText(userStatus);

    Glide
            .with(context)
            .load(userProfilePic)
            .apply(RequestOptions.circleCropTransform())
            .into(holder.mAvatarIv);

    //Handle item click
    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            /*Click user from user list to start conversation
             *Start Activity by putting UID of receiver
             *we will use that UID to identify the user we are gonna chat */

            Intent intent = new Intent(context, ChatActivity.class);
            intent.putExtra("userUid", userUID);
            context.startActivity(intent);

        }
    });

}

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

class MyHolder extends RecyclerView.ViewHolder {

    ImageView mAvatarIv;
    TextView mNameTv, mNicknameTv, mStatusTv;

    public MyHolder(@NonNull View itemView) {
        super(itemView);

        mAvatarIv = itemView.findViewById(R.id.avatarIv);
        mNameTv = itemView.findViewById(R.id.nameTv);
        mNicknameTv = itemView.findViewById(R.id.nicknameTv);
        mStatusTv = itemView.findViewById(R.id.statusTv);

        mStatusTv.setEllipsize(TextUtils.TruncateAt.MARQUEE);
        mStatusTv.setSelected(true);
        mStatusTv.setSingleLine(true);

    }
}

} }

Currently, you are querying your realtime database and ordering by its key name.目前,您正在查询实时数据库并按其键名排序。 To sort the RecyclerView list, you can try two approaches from here:要对 RecyclerView 列表进行排序,您可以从这里尝试两种方法:

  1. Querying in such a way that you get results ordered by the last message timestamp.以这样一种方式进行查询,您可以获得按最后一条消息时间戳排序的结果。
  2. Manually process and sort at the RecyclerView adapter to display latest chat at the top.在 RecyclerView 适配器上手动处理和排序以在顶部显示最新聊天。

For approach one, you can try using your query like this:对于方法一,您可以尝试使用这样的查询:

Query query = reference.orderByChild("last_msg_time_stamp").limitToLast(10000);

Here, last_msg_time_stamp might be the key inside Chats/$your_keys which holds the last timestamp for that conversation.在这里, last_msg_time_stamp可能是Chats/$your_keys中的键,它保存了该对话的最后一个时间戳。 For approach two, I would say that in your adapter, you are taking this data and putting it.对于方法二,我会说在您的适配器中,您正在获取这些数据并将其放入。 But before binding this data into list, you need to sort your list on the basis of your last message timestamp for all of the keys.但在将此数据绑定到列表之前,您需要根据所有键的最后一条消息时间戳对列表进行排序。

In my view, It would be beneficial to use approach one, since, it would be less processing-intensive way for the users.在我看来,使用方法一将是有益的,因为它对用户来说是一种处理密集程度较低的方式。 The realtime database would be pre-processing and the required list for you already.实时数据库将进行预处理,并且已经为您提供所需的列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何使Recyclerview出现在mapview的顶部 - How do i make Recyclerview appear on top of mapview 每次将项目添加到列表时如何使RecyclerView不会滚动到底部 - How to make RecyclerView not scroll to the bottom each time an item is added to the list SQL:我从中收到消息或向其发送消息的十个第一联系人,以及他们最近发送的消息和时间 - SQL: ten first contacts that I have received message from or sent to along with their latest sent message and time 如何使该Java读取整个最后一行,而不是一次读取每个字节? - How can I make this Java read the whole last line, and not just each byte at a time? RecyclerView,显示我在recyclerView上发送的最后一条消息 - RecyclerView, show last message i send on recyclerView 如何修复此代码以为每个用户进行收集? - How can I fix this code to make collection for each user? 如何在简单的UDP服务器中检查发送的消息是否与接收的消息相同 - How to check if the sent message is the same as the received message in a simple UDP server 如何检查收到的信标是持续 2 分钟的信标? - How can I check that the received beacon is a beacon that last 2 minutes? 如何在使用自定义方式保存数据 RecyclerView 时制作列表更改动画 - How can I make list changes animations while using custom way of saving data RecyclerView 如何按大多数用户的位置顺序显示我的列表 (RecyclerView)? - How can I display my list (RecyclerView) in order of the most user's location?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM