我正在开发一款聊天应用。 ChatFragment有一个chatList,它从Firebase实时数据库中获取数据,并使用childEventListener(onChildAdded)逐个添加项目。
当方向改变或用户离开片段时,我想保留收到的chatList,删除监听器,然后在用户返回聊天片段或完成方向更改时重新连接监听器。
问题是,当重新创建活动/片段时,childEventListener丢失了,所以我必须重新创建新的监听器。但是后来chatList被复制了,因为调用了onChildAdded并再次添加了所有项目。
我试过了
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
但它没有用,它仍然调用onChildAdded。然后,使用singleValueEventListener的每个查询都将无法正常工作,因为它请求缓存的数据,而不是实时数据库。
我想将chatList的项目与onChildAdded中收到的项目进行比较,如果它存在,则跳过它。但这是浪费时间,而不是我想要做的事情:保留当前数据,无需从firebase DB重新加载,并且还保留新项目的监听器。
或者我可以保存所有听众并以某种方式将其取回,我不知道。
这是我的活动和片段的一些代码
在HomeActivity中,将片段保存到bundle的代码
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (chatListFragment.isAdded())
getSupportFragmentManager().putFragment(outState, ChatListFragment.TAG, chatListFragment);
}
然后我把它放回onCreate()。在这里,所有片段的字段都丢失了:chatList,listener ...
if(getSupportFragmentManager().getFragment(savedInstanceState, ChatListFragment.TAG) != null) {
chatListFragment = getSupportFragmentManager().getFragment(savedInstanceState, ChatListFragment.TAG);
}
在ChatFragment中,我将聊天列表保存在bundle中
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList(KEY_CHAT_LIST, chatList);
outState.putInt(KEY_CURRENT_POSITION, currentItemPosition);
//TODO: save data
}
我把它放回onActivityCreated()
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(savedInstanceState != null) {
chatList = savedInstanceState.getParcelableArrayList(KEY_CHAT_LIST);
currentItemPosition = savedInstanceState.getInt(KEY_CURRENT_POSITION);
chatListAdapter.setChatList(chatList);
chatListAdapter.notifyDataSetChanged();
//the method below gets data from firebase DB by creating a
//childEventListener, that mean it gets all the chat item again
//but if I don't call it, I can't listen to onChildAdded :((
//presenter.loadChatList(chatList);
} else {
chatList.clear();
chatListAdapter.setChatList(chatList);
chatListAdapter.notifyDataSetChanged();
presenter.loadChatList(chatList);
}
}
因此,简而言之,我希望在重新启动/重新创建活动/片段时不要使用setPersistenceEnabled(true)来保留新项目/更改项目的数据和所有firebase侦听器。
对不起,我的英语不好。非常感谢。
不知道为什么重新创建活动(和片段),在片段中保存实例状态是正确的做法。但是,您应该在Fragment.onCreate(savedInstanceState)中检索数据。这是第一个被调用的方法,也是设置非图形数据的好地方