我正在开发一个显示项目列表的应用程序,并允许用户添加更多项目并检查项目的详细信息。如何在使用Firebase数据库恢复活动时正确恢复数据?
比方说,我把我的数据库引用在活动中,加入ChildEventListener
听众onResume()
和onPause()
删除它们:
public void onResume() {
super.onResume();
mItemChildEventListener = mDatabaseReference.child('items').addChildEventListener(new ChildEventListener() {
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
mAdapter.addItem(dataSnapshot.getValue(Item.class));
}
...
};
}
public void onPause() {
super.onPause();
if (mItemChildEventListener != null) {
mDatabaseReference.removeEventListener(mItemChildEventListener);
}
}
在这些ChildEventListener
,我通过项目添加项目到项目的列表和在适配器中调用notifyItemInserted(itemArray.size() - 1)
。
public void addItem(Item item) {
if (mItems == null) {
mItems = new ArrayList<>();
}
mItems.add(item);
notifyItemInserted(mItems.size() - 1);
}
而且,保持平稳运行,我保持一个Reteiner Fragment项目列表中的应用,保存此值onSaveInstanceState()
并恢复他们onCreate()
。
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (savedInstanceState != null) {
mItems = getState(STATE_ITEMS);
} else {
mItems = new ArrayList<>();
}
mAdapter = new ItemAdapter(mItems);
}
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveState(STATE_ITEMS, mItems);
}
public <T> T getState(String key) {
//noinspection unchecked
return (T) mRetainedFragment.map.get(key);
}
public void saveState(String key, Object value) {
mRetainedFragment.map.put(key, value);
}
public static class RetainedFragment extends Fragment {
HashMap<String, Object> map = new HashMap<>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// retain this fragment
setRetainInstance(true);
}
}
但是,如果我注销并重新注册监听器,例如,由任何方向改变或离开和returting到活动中,一如预期,onResume()
将被调用,并通过再次加入ChildEventListener
,同数据被检索到,如果它不与已经包含在项目列表中的数据进行比较mItems
,它将被复制。另外,如果我没有保存项目列表mItems
,并且每次调用onResume()
时检索数据,则列表会丢失其滚动位置并且也会闪烁,因为检索数据需要一些时间。
问题
我怎能不再次再次检索它们检索到的项目列表,但要继续收听,在已经获取的项目更改,并且增加了新的项目?有没有更好的解决方案比比较已经检索的项目与新项目,例如,通过他们的关键?
我试过寻找文档和其他问题,但我找不到与这种情况有关的任何信息。另外,我已经试着将参考mDatabaseReference
保留在onSaveInstanceState()
中,正如我对mItems
项目的列表所做的那样,但它也没有奏效。
@rewgoes如果你有一个DatabaseHelper类,并且你使用RecyclerAdapter作为一个View Holder,如果你可以将你的数据加载到一个ArrayList中,那么当你添加Update或Delete时你只需要去一个数据库,所以这个是我使用Sqlite的MVP设计 – Grendel
@grendel,我没有使用DatabaseHelper。我的数据库完全基于Firebase实时数据库。 – rewgoes
@MarianoCórdoba这些模式本身并不一定会帮助OP正在经历的问题。您以这种方式构建的基础架构仍然容易被拆除,并且每次配置更改都会重新创建基础架构,除非您仍然执行一些特殊的操作来保留数据模型层。 –