Wierzę, że FragmentStatePagerAdapter nie zachowuje się poprawnie, przesuwając getItemPosition(Object object)
w celu zmiany kolejności stron.Zmienianie kolejności stron w FragmentStatePagerAdapter przy użyciu getItemPosition (obiektu obiektu)
Poniżej znajduje się prosty przykład. W stanie początkowym kolejność stron to {A, B, C}. Po wywołaniu toggleState()
kolejność stron zmienia się na {A, C, B}. Przesłaniając getItemPosition(Object object)
, zapewniamy, że wyświetlana strona (A, B lub C) nie ulegnie zmianie.
public static class TestPagerAdapter extends FragmentStatePagerAdapter {
private boolean mState = true;
public TestPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
@Override
public int getCount() {
return 3;
}
private void toggleState() {
mState = !mState;
notifyDataSetChanged();
}
private String getLabel(int position) {
switch (position) {
case 0:
return "A";
case 1:
return mState ? "B" : "C";
default:
return mState ? "C" : "B";
}
}
@Override
public int getItemPosition(Object object) {
String label = ((TestFragment) object).getLabel();
if (label.equals("A")) {
return 0;
} else if (label.equals("B")) {
return mState ? 1 : 2;
} else {
return mState ? 2 : 1;
}
}
@Override
public CharSequence getPageTitle(int position) {
return getLabel(position);
}
@Override
public Fragment getItem(int position) {
return TestFragment.newInstance(getLabel(position));
}
}
Napotkałem dwa osobne zachowania, które wydają się nieprawidłowe.
Gdybym od razu zadzwonić
toggleState()
(podczas oglądania strona A, przed przesuwając do jakiejkolwiek innej strony), awarii aplikacji.java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2 at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251) at java.util.ArrayList.set(ArrayList.java:477) at android.support.v4.app.FragmentStatePagerAdapter.destroyItem(FragmentStatePagerAdapter.java:136) at android.support.v4.view.ViewPager.populate(ViewPager.java:867) at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:469) at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:441) at android.support.v4.view.ViewPager.dataSetChanged(ViewPager.java:766) at android.support.v4.view.ViewPager$PagerObserver.onChanged(ViewPager.java:2519) at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37) at android.support.v4.view.PagerAdapter.notifyDataSetChanged(PagerAdapter.java:276) at com.ugglynoodle.test.testfragmentstatepageradapter.MainActivity$TestPagerAdapter.toggleState(MainActivity.java:55) ...
Patrząc na źródło
FragmentStatePagerAdapter
ta będzie ustalona przez pierwsze sprawdzenie rozmiarumFragments
(jak w wierszach 113-115) przed wywołaniemset()
w linii 136.Gdybym pierwszy swipe do strona B, następnie
getItem(2)
jest wywoływana, strona C jest tworzona, amFragments
ma teraz rozmiar 3 (to zapobiegnie zaistnieniu awarii powyżej). Następnie przeciągam z powrotem na stronę A, a strona C jest zniszczona, tak jak powinna być (ponieważ jest oddalona o 2 strony i używam domyślnego limitu strony 1). Teraz nazywam siętoggleState()
. Strona B jest teraz zniszczona. Jednak strona C NIE jest odtwarzana! Oznacza to, że gdy przesuniemy teraz w prawo, otrzymuję pustą stronę.
Po pierwsze, byłoby miło wiedzieć, czy mam rację, a są to w rzeczywistości błędy lub czy robię coś nie tak. Jeśli są to błędy, czy ktoś może zaproponować obejście (inne niż debugowanie i przebudowywanie biblioteki wsparcia osobiście)? Z pewnością ktoś musiał z powodzeniem zastąpić getItemPosition(Object object)
(oprócz ustawienia wszystkiego na POSITION_NONE
)?
Używam aktualnej wersji (10) biblioteki pomocy technicznej.
użyłem swoją stałą realizację, jednak jeden problem, że jestem stoi to NIE updation fragmentów sąsiadujących w ViewPager.How mogę to naprawić? –
Wydaje mi się, że jesteś na miejscu, @UgglyNoodle, chciałem tylko wskazać, że jeśli wszystko jest w porządku, gdy fragmenty zostaną zamienione i odtworzone, zwracana jest pozycja POSITION_NONE dla fragmentów, których kolejność się zmieniła, i POSTION_UNCHANGED dla fragmentów, które się nie zmieniły. osiąga również pożądany wynik bez awarii. –