So behalten Sie RecyclerView position nach Ausrichtung ändern, während mit FB & ChildEventListener?

Arbeite ich an einem einfachen APOD-app implementiert:

  • RecyclerView
  • CardView
  • Firebase
  • Picasso

Die app packt Bilder und text aus Firebase und Firebase Storage, zeigt Sie in einem CardView, und setzt ein OnClickListener jedem View. Wenn der Benutzer klickt auf ein Bild, öffne ich ein neues Activity durch eine Intent. Die zweite Activity zeigt das original-Bild geklickt, und mehr info über es.

Habe ich umgesetzt, diese mit einem GridLayoutManager 1 Spalte, wenn der Benutzer das Telefon SENKRECHT, 3 Spalten, wenn der Benutzer das Telefon HORIZONTAL.

Das problem das ich habe ist ich kann nicht scheinen, um speichern Sie die RecyclerView's position auf Orientierung ändern. Ich habe versucht, jede einzelne option, die ich finden konnte, aber keiner scheint zu funktionieren. Die einzige Schlussfolgerung, die ich kommen könnte, ist, dass auf rotation, ich Zerstöre Firebase's ChildEventListener um Speicherlecks zu vermeiden, und sobald die Ausrichtung abgeschlossen ist, wird Firebase re-Abfragen der Datenbank, weil die neue Instanz von ChildEventListener.

Gibt es eine Möglichkeit, ich kann speichern mein RecyclerView's position auf die Ausrichtung ändern? Ich will nicht android:configChanges wie es lässt mich nicht ändern, mein layout, und ich habe auch schon versucht das speichern als Parcelable, die nicht erfolgreich war. Ich bin sicher, es ist etwas einfach, ich bin fehlt, aber hey, ich bin neu zu entwickeln. Jede Hilfe oder Anregungen zu meinem code ist sehr geschätzt. Danke!

Unten sind meine Klassen, die ich verkürzt nur den erforderlichen code.

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);
    }
  }

}
  • Ich denke, das problem ist, dass die neue RV nach einer Konfigurationsänderung, die nicht wissen, etwas über seinen Inhalt anzeigen am Ende von onCreate, da diese Daten kommt nur, nachdem alle untergeordneten Zuhörer auslösen. Damit es nicht zu wissen, wie vollständig wiederherzustellen, da es denkt, dass es leer zu dieser Zeit. Ich weiß nicht, eine Lösung ohne weiteres, wollte aber um diese info. Sie können die Abfrage eines RV der scroll-offset, wenn das hilft.
  • Vielen Dank, Doug, ich habe versucht, das speichern und wiederherstellen der position, konnte aber nicht zum laufen bekommen. Ich dachte dieser Beitrag würde mehr Aufmerksamkeit bekommen, da bin ich entweder völlig fehlt etwas, oder FB macht es schwer zu realisieren, diese Art der Sache. Ich werde es weiter versuchen und werde zu aktualisieren meinem Beitrag, wenn ich nichts anderes findest.
InformationsquelleAutor Drew Szurko | 2017-02-28
Schreibe einen Kommentar