我正在實現一個簡單的APOD應用:如何在使用Firebase和ChildEventListener的方向更改後保留RecyclerView的位置?
RecyclerView
CardView
Firebase
Picasso
該應用從Firebase
和Firebase Storage
抓住圖像和文字,將它們顯示在CardView
中,並設置一個OnClickListener
每個View
。當用戶點擊圖片時,我通過Intent
打開新的Activity
。第二個Activity
顯示原始點擊的圖像,以及更多關於它的信息。
我已經實現了這一切,使用GridLayoutManager
,如果用戶的手機是VERTICAL,則爲1列,如果用戶的手機爲HORIZONTAL,則爲3列。
我遇到的問題是我似乎無法保存RecyclerView
對方向更改的立場。我嘗試了所有可以找到的選項,但沒有一個可以工作。我能想到的唯一結論是,在輪換時,我正在銷燬Firebase
的ChildEventListener
以避免內存泄漏,一旦定位完成,Firebase
由於ChildEventListener
的新實例而重新查詢數據庫。
有沒有什麼辦法可以保存我的RecyclerView
對方向改變的立場?我不想android:configChanges
,因爲它不會讓我改變我的佈局,並且我已經嘗試將其保存爲Parcelable
,這是不成功的。我確定這件事很容易失蹤,但是,嘿,我是新手開發的。我非常感謝我的代碼的任何幫助或建議。謝謝!
下面是我的課程,我只縮短了必要的代碼。
MainActivity
public class MainActivity extends AppCompatActivity {
private RecyclerAdapter mRecyclerAdapter;
private DatabaseReference mDatabaseReference;
private RecyclerView mRecyclerView;
private Query query;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
setContentView(R.layout.activity_main);
getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final int columns = getResources().getInteger(R.integer.gallery_columns);
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
query = mDatabaseReference.child("apod").orderByChild("date");
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new GridLayoutManager(this, columns));
mRecyclerAdapter = new RecyclerAdapter(this, query);
mRecyclerView.setAdapter(mRecyclerAdapter);
}
@Override
public void onDestroy() {
mRecyclerAdapter.cleanupListener();
}
}
RecyclerAdapter
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ApodViewHolder> {
private final Context mContext;
private final ChildEventListener mChildEventListener;
private final Query mDatabaseReference;
private final List<String> apodListIds = new ArrayList<>();
private final List<Apod> apodList = new ArrayList<>();
public RecyclerAdapter(final Context context, Query ref) {
mContext = context;
mDatabaseReference = ref;
ChildEventListener childEventListener = new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
int oldListSize = getItemCount();
Apod apod = dataSnapshot.getValue(Apod.class);
//Add data and IDs to the list
apodListIds.add(dataSnapshot.getKey());
apodList.add(apod);
//Update the RecyclerView
notifyItemInserted(oldListSize - getItemCount() - 1);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
String apodKey = dataSnapshot.getKey();
int apodIndex = apodListIds.indexOf(apodKey);
if (apodIndex > -1) {
// Remove data and IDs from the list
apodListIds.remove(apodIndex);
apodList.remove(apodIndex);
// Update the RecyclerView
notifyDataSetChanged();
}
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
};
ref.addChildEventListener(childEventListener);
mChildEventListener = childEventListener;
}
@Override
public int getItemCount() {
return apodList.size();
}
public void cleanupListener() {
if (mChildEventListener != null) {
mDatabaseReference.removeEventListener(mChildEventListener);
}
}
}
我認爲這個問題是一個配置更改後的新RV不在onCreate結束時瞭解其視圖內容的任何內容,因爲只有在所有子監聽器觸發後纔會進入該數據。所以它不知道如何完全恢復自己,因爲它認爲它當時是空的。我不知道解決方案,但確實想提供這些信息。你可以查詢RV的滾動偏移量,如果有幫助的話。 –
@DougStevenson。非常感謝道格,我試着挽救和恢復職位,但無法實現。我認爲這篇文章會得到更多的關注,因爲我完全錯過了一些東西,或者Firebase很難實現這樣的事情。如果我找到其他東西,我會繼續嘗試並更新我的帖子。 –