Ich versuche, das gleiche Design als PlayStore 5.1.x zu haben. Hier ist mein Layout:ViewPager erstes Fragment ist immer falsch mit FragmentStatePager
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|center_horizontal"
android:gravity="center_vertical|center_horizontal"
android:orientation="vertical">
<com.astuetz.PagerSlidingTabStrip
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/background_tabs" />
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Mein Adapter:
public class MainPagerAdapter extends FragmentStatePagerAdapter {
private ArrayList<FakeFragment> fragments;
public MainPagerAdapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
fragments = new ArrayList<FakeFragment>();
}
@Override
public Fragment getItem(int position) {
// TODO Auto-generated method stub
if(position < getCount()) {
FakeFragment fragment = FakeFragment.newInstance(position);
fragments.add(fragment);
}
return fragments.get(position);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return Category.values().length;
}
@Override
public CharSequence getPageTitle(int position) {
// TODO Auto-generated method stub
return Category.values()[position].getTitle();
}
@Override
public int getItemPosition(Object object) {
// TODO Auto-generated method stub
return POSITION_NONE;
}
}
Meine Tabs und Pager zeigen richtig! aber ich habe bemerkt, dass das erste Fragment, das im View-Pager angezeigt wird, immer dasselbe ist wie das zweite. Dann, wenn ich einmal, zweimal wische und zurück zur ersten Seite wische, finde ich, dass das korrekte Fragment jetzt gezeigt wird !!
Ich kann nicht verstehen, warum dieses Verhalten, bitte ich brauche einige Erklärungen.
SOLUTION
Das Problem war, meine FakeFragment.newInstance()
Methodendefinition zurückzuführen.
private static int position;
public static FakeFragment newInstance(int position) {
// TODO Auto-generated method stub
FakeFragment.position = position;
return new FakeFragment();
}
habe ich es durch ein setArguments(args)
meine FakeFragment
Instanz verwendet wird, und es dann in onCreate
Methode abrufen. Jetzt funktioniert alles gut!
Kann mir jemand erklären warum?
Ich denke, dass auf diese Weise Wert der Position wird vollständig abhängig von Fragment Lebenszyklus, so wird immer die erwartete Position sein, nicht wahr?
Entfernen Sie 'private ArrayList -Fragmente' und geben Sie mit' getItem() 'eine neue Instanz des Fragments zurück. Der ** komplette und vollständige * Punkt *** hinter 'FragmentStatePagerAdapter' soll ** NICHT ** alle Fragmente im Speicher halten. Wenn das das ist, was Sie wollen, dann werden Sie immer noch die 'ArrayList ' los und wechseln Sie Ihren Adapter zu einem 'FragmentPagerAdapter' anstatt einem' FragmentStatePagerAdapter'. Befreie auch 'getItemPosition()'. [FWIW, hier sind eine Reihe von Beispielen 'ViewPager'-Apps] (https://github.com/commonsguy/cw-omnibus/tree/master/ViewPager). –
CommonsWare
Danke @CommonsWare. Ich habe den 'FragmentStatePagerAdapter' gewählt, weil ich 6 Seiten in meinem' ViewPager' habe, auf jeder Seite habe ich eine 'GridView' mit vielen Daten zum Anzeigen.Deshalb wollte ich diese Art von Adapter verwenden, um eine Seite neu zu erstellen oder den Inhalt nur bei Bedarf zu aktualisieren. Deshalb habe ich auch versucht, 'getItemPosition' zu überschreiben. Ist das mit 'FragmentPagerAdapter' möglich? danke nochmal für die antwort! –
Ihre Implementierung sollte in beiden Fällen korrekt funktionieren, nur die Geschwindigkeit kann unterschiedlich sein. Wenn das Laden von Daten teuer ist und Sie nicht jedes Mal 'FragmentStatePagerAdapter' verwenden müssen, verwenden Sie 'Fragment.onSaveInstanceState', um den geladenen Datensatz zu speichern. –