私が実装して、簡単なAPODアプリに取り組んでいる:アプリは、Firebase
とFirebase Storage
から画像やテキストをつかむFirebase&ChildEventListenerを使ってオリエンテーションを変更した後、RecyclerViewの位置を保持する方法は?
RecyclerView
CardView
Firebase
Picasso
それらをCardView
に表示し、 OnClickListener
をそれぞれView
に設定します。ユーザーが画像をクリックすると、新しいActivity
がIntent
で開かれます。 2番目のActivity
には、クリックされた元の画像と詳細な情報が表示されます。
GridLayoutManager
(ユーザーの電話がVERTICALの場合は1列、HORIZONTALの場合は3列)を使用してこのすべてを実装しました。
私が抱えている問題は、オリエンテーションの変更でRecyclerView
の位置を保存できないようです。私は見つけることができるすべてのオプションを試しましたが、うまくいかないようです。私が思いつくことができる唯一の結論は、ローテーション時に、メモリリークを避けるためにのChildEventListener
を破棄していて、方向が完了すると、新しいインスタンスChildEventListener
のためにFirebase
がデータベースを再クエリします。
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。 –
ありがとうDoug、私は位置を保存して復元しようとしましたが、動作させることができませんでした。私はこの記事がもっと注目されると思っていました。なぜなら、何かが完全に欠けているか、Firebaseがこのようなことを実装するのを難しくしているからです。私は何かを見つけたら、私の投稿を更新しようとし続けます。 –