Я веду чат, используя Firebase для хранения сообщений и RecyclerView
для их отображения.Согласно приведенному ниже конструктору адаптеров, при инициализации RecyclerView
последние 50 сообщений запрашиваются из Cloud Firestore и располагаются в порядке убывания с помощью временной метки Unix.Затем я использую setStackFromEnd (true) в своей активности чата, чтобы перевернуть порядок их отображения, так как самые новые сообщения должны быть внизу, а новые сообщения добавляются в список сообщений адаптера с помощью messageList.add (0, message)
Это представляет проблему.В onBindViewHolder ранее приемлемое:
Message message = messageList.get(position);
holder.message.setText(message.getMessage());
holder.author.setText(message.getAuthor() + ":");
больше не работает, поскольку сообщение, вводимое в RecyclerView, будет повторять самое последнее сообщение при загрузке RecyclerView (то, которое находится в позиции 0).то есть:
- сообщение одно
- сообщение одно
- сообщение одно
- сообщение одно
Вместо:
- сообщение одно
- сообщение два
- сообщение три
- сообщение четыре
Где «сообщение одно» - этосамое последнее сообщение при создании RecyclerView
.Заменив это на:
Message message = messageList.get(0);
holder.message.setText(message.getMessage());
holder.author.setText(message.getAuthor() + ":");
В onBindViewHolder
, чтобы получить истинное самое последнее сообщение, оно появится на экране, но также впоследствии заменит все элементы самым последним сообщением при их переработке.В конечном счете, я бы хотел, чтобы запрашиваемые сообщения перечислялись снизу вверх в порядке их актуальности, продолжая при этом размещать самые новые сообщения внизу (как любое приложение чата) без необходимости запрашивать всю коллекцию.Где и как исправить ошибку?
Конструктор адаптера:
public ChatRecyclerViewAdapter(Context mContext, ArrayList<String> mMessage, ArrayList<String> mAuthor, String mRoomID, FirebaseFirestore firestore) {
messageList = new ArrayList<>();
firestore = FirebaseFirestore.getInstance();
mCollection = firestore.collection(mRoomID + "_messages");
Query query = mCollection.orderBy("timestamp", Query.Direction.DESCENDING).limit(50);
query.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
for (DocumentChange documentChange : queryDocumentSnapshots.getDocumentChanges()) {
switch (documentChange.getType()) {
case ADDED:
documentChange.getDocument();
Message message = documentChange.getDocument().toObject(Message.class);
messageList.add(0,message);
notifyItemInserted(messageList.size());
}
}
}
});
Попытка запроса следующего набора старых сообщений при прокрутке:
query.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
if (queryDocumentSnapshots.size() > 0) {
//Get the last visible document
DocumentSnapshot lastVisible = queryDocumentSnapshots.getDocuments().get(messageList.size()-1);
//Construct a new query starting at this document and get the next batch of messages
Query next = mCollection.orderBy("timestamp", Query.Direction.DESCENDING).startAfter(lastVisible).limit(20);
next.get();
}
}
});