问题
I have implemented a chat function in my app and it's working fine, only problem is that now I want the chats to be ordered by timestamp
, so that the newest ones come first and the oldest come last. I have tried doing so using Comparator, but for some reason it's not working and I am not sure how to fix it.
Below you have my MessageActivity
where I save the chats to the Firebase, and my ChatFragment
that contains the ArrayList
for the chats. The chats are appearing there, but I can't get them by any means to rearrange themselves and get in order by Timestamp.
Someone mind telling me how to fix this?
ChatFragment
public class ChatsFragment extends Fragment {
private RecyclerView mRecyclerView;
private UserAdapterChat mUserAdapterChat;
private List<User> mUsers;
private List<Chatlist> mChatList;
private FirebaseUser mFirebaseUser;
private TextView mNoMessages;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_chats, container, false);
mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
mNoMessages = v.findViewById(R.id.no_messages);
mRecyclerView = v.findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
mRecyclerView.setLayoutManager(linearLayoutManager);
mChatList = new ArrayList<>();
mUserAdapterChat = new UserAdapterChat(getContext(), mUsers, false);
mRecyclerView.setAdapter(mUserAdapterChat);
mUsers = new ArrayList<>();
EditText search_users = v.findViewById(R.id.search_bar);
search_users.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
searchUsers(s.toString().toLowerCase());
}
@Override
public void afterTextChanged(Editable s) {
}
});
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Chatlist").child(mFirebaseUser.getUid());
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
Log.d("CHAT", dataSnapshot.toString());
mChatList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Chatlist chatlist = snapshot.getValue(Chatlist.class);
mChatList.add(chatlist);
}
if (mChatList.size() == 0) {
mNoMessages.setVisibility(View.VISIBLE);
} else {
mNoMessages.setVisibility(View.GONE);
chatList();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
Task<InstanceIdResult> task = FirebaseInstanceId.getInstance().getInstanceId();
task.addOnCompleteListener(task1 -> {
if (task1.isSuccessful()) {
String token = task1.getResult().getToken();
updateToken(token);
} else {
Exception exception = task1.getException();
Log.d("TOKEN", exception.getMessage());
}
});
return v;
}
private void updateToken(String token) {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Tokens");
Token token1 = new Token(token);
reference.child(mFirebaseUser.getUid()).setValue(token1);
}
private void searchUsers(String s) {
Query query = FirebaseDatabase.getInstance().getReference("Users").orderByChild("username").startAt(s).endAt(s + "\uf8ff");
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mUsers.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
User user = snapshot.getValue(User.class);
if (s.length() == 0) {
mUsers.clear();
} else {
if (user != null) {
if (!user.getId().equals(mFirebaseUser.getUid())) {
mUsers.add(user);
mNoMessages.setVisibility(View.GONE);
}
}
}
}
mUserAdapterChat = new UserAdapterChat(getContext(), mUsers, false);
mUserAdapterChat.notifyDataSetChanged();
mRecyclerView.setAdapter(mUserAdapterChat);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
private void chatList() {
mUsers = new ArrayList<>(mChatList.size());
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
reference.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mUsers.clear();
Collections.sort(mChatList, ChatsFragment.this::compare);
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
User user = snapshot.getValue(User.class);
for (int i = 0; i < mChatList.size(); i++) {
if (mFirebaseUser != null && user != null) {
if (!user.getId().equals(mFirebaseUser.getUid()) && user.getId().equals(mChatList.get(i).receiver)) {
ensureSize((ArrayList<?>) mUsers, mChatList.size());
mUsers.set(i, user);
}
}
}
}
mUserAdapterChat = new UserAdapterChat(getContext(), mUsers, true);
mUserAdapterChat.notifyDataSetChanged();
mRecyclerView.setAdapter(mUserAdapterChat);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
public static void ensureSize(ArrayList<?> list, int size) {
list.ensureCapacity(size);
while (list.size() < size) {
list.add(null);
}
}
public int compare(Chatlist o1, Chatlist o2) {
return o1.getTimestamp() < o2.getTimestamp() ? 1 : (o1.getTimestamp() == o2.getTimestamp() ? 0 : -1);
}
}
回答1:
You are sorting collection in ascending order by using Long.compare(). For showing latest chat you need to change the compare method as
public int compare(Chatlist o1, Chatlist o2) {
return o1.getTimestamp() < o2.getTimestamp() ? 1 :
(o1.getTimestamp == o2.getTimestamp() ? 0 : -1);
}
回答2:
You can simply use Java8 feature to compare the element as below:
List<ChatList> unique = list.stream().collect(collectingAndThen(toCollection(() -> new TreeSet<>(comparing(ChatList::getTimestamp))),ArrayList::new));
unique.forEach((k) -> System.out.println(k.getTimestamp()));
来源:https://stackoverflow.com/questions/63090111/want-to-order-chats-in-arraylist-by-timestamp-using-comparator-but-its-not-wor