【发布时间】:2018-11-12 20:51:47
【问题描述】:
我有一个聊天活动,它使用 Firebase 查询按倒序的RecyclerView 的底部到顶部的降序加载聊天室的 5 条最新消息。加载这些消息后发送到 Firebase 集合的消息通过更改位置显示在屏幕底部,在调用 onEvent 后将新列表项插入到列表中。这是我的代码:
private void initRecyclerView() {
//initializes and sets adapter/resets variables
mAdapter = new ChatRecyclerViewAdapter(mMessages);
mRecyclerView.setAdapter(mAdapter);
firstEventListenerCalled = false;
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setReverseLayout(true);
mRecyclerView.setLayoutManager(linearLayoutManager);
Query query = mCollection.orderBy("timestamp", Query.Direction.DESCENDING).limit(5;
firstRegistration = query.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
Log.d("First SnapshotListener", "Called");
for (DocumentChange documentChange : queryDocumentSnapshots.getDocumentChanges()) {
switch (documentChange.getType()) {
case ADDED:
//Creates listener for queried messages that puts messages retrieved during initial query at end of message list,
// then another one after one runs its course that puts new ones at the beginning of the list
if (!firstEventListenerCalled) {
Message message = documentChange.getDocument().toObject(Message.class);
mMessages.add(message);
mAdapter.notifyDataSetChanged();
} else if (firstEventListenerCalled) {
Message message = documentChange.getDocument().toObject(Message.class);
mMessages.add(0, message);
mAdapter.notifyDataSetChanged();
Log.d(TAG, "newMessageAdded " + message.getMessage());
}
}
}
firstEventListenerCalled = true;
}
});
我正在尝试删除activity的onStop()方法中的ListenerRegistration,清除onRestart()方法中RecyclerView的内容,然后在onStart()中重新调用上面的方法,这样Activity 停止时没有消息进入,并且在此期间发送的任何消息都出现在 Activity 重新启动时由 initRecyclerView() 方法查询的 5 条消息中:
@Override
protected void onRestart() {
super.onRestart();
mMessages.clear();
mAdapter.notifyItemRangeRemoved(0, mMessages.size());
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart Called");
initRecyclerView();
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop Called");
firstRegistration.remove();
if (refreshRegistraton != null) {
refreshRegistraton.remove();
}
}
@Override
public void onBackPressed() {
finish();
}
但是,使用此策略重新启动 Activity 时会发生以下情况:
- 查询到的 5 条消息以正确的顺序出现
-
活动停止时发送的任何消息都显示在这 5 条消息之外,并且以相反的顺序显示:
旧消息 1
旧消息 2
旧消息 3
旧消息 4
旧消息 5
停止时发送的消息 2
停止时发送的消息 1
新消息似乎是按照firstEventListenerCalled == true 时所描述的顺序加载的,但在每次调用 initRecyclerView() 方法的开头时都将其设为 false。它们根本不应该被单独加载,因为我删除了侦听器并完全重新创建了RecyclerView。我错过了什么?
【问题讨论】:
-
不要重复提问。编辑旧的,解释为什么它不是重复的,如果至少有 5 人同意,它将重新打开。
-
下次注意。
标签: android firebase google-cloud-firestore