[英]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 列表进行排序,您可以从这里尝试两种方法:
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.