我正在開發一個顯示項目列表的應用程序,並允許用戶添加更多項目並檢查項目的詳細信息。如何在使用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正在經歷的問題。您以這種方式構建的基礎架構仍然容易被拆除,並且每次配置更改都會重新創建基礎架構,除非您仍然執行一些特殊的操作來保留數據模型層。 –