Я работаю над простым приложением APOD, которое реализует:
-
RecyclerView
-
CardView
-
Firebase
-
Picasso
Приложение захватывает изображения и текст из Firebase
и Firebase Storage
, отображает их в CardView
и устанавливает OnClickListener
для каждого View
. Когда пользователь нажимает на изображение, я открываю новую Activity
через Intent
. Вторая Activity
отображает исходное изображение с кликом и дополнительную информацию об этом.
Я реализовал все это, используя столбец GridLayoutManager
, 1, если пользовательский телефон VERTICAL, 3 столбца, если пользовательский телефон HORIZONTAL.
Проблема, с которой я сталкиваюсь, заключается в том, что я не могу сохранить позицию RecyclerView
при изменении ориентации. Я пробовал все, что мог найти, но никто не работает. Единственный вывод, который я мог придумать, заключается в том, что при ротации я уничтожаю Firebase
ChildEventListener
чтобы избежать утечки памяти, и как только ориентация завершена, Firebase
повторно запрашивает базу данных из-за нового экземпляра ChildEventListener
.
Есть ли способ сохранить позицию RecyclerView
при изменении ориентации? Я не хочу android:configChanges
поскольку он не позволит мне изменить мой макет, и я уже пытался сохранить как Parcelable
, что было неудачно. Я уверен, что это что-то легкое, мне не хватает, но, эй, я новичок в разработке. Любая помощь или предложения по моему коду очень приветствуются. Благодарю!
Ниже приведены мои классы, которые я сократил только до необходимого кода.
Основная деятельность
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);
}
}
}