Mam ViewPager z trzema elementami. Próbuję ustawić ViewPager, aby wyświetlić stronę najbardziej na prawo (który byłby drugi element). Zwraca to wyjątek IndexOutOfBounds, choć wiem, że indeks powinien znajdować się w granicach. Oto dokładny stos:Android ViewPager rzuca wyjątek IndexOutOfBounds przy ustawianiu bieżącego elementu/strony
02-22 12:22:50.256: E/AndroidRuntime(384): FATAL EXCEPTION: main
02-22 12:22:50.256: E/AndroidRuntime(384): java.lang.IndexOutOfBoundsException: index=1 count=0
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.addInArray(ViewGroup.java:2050)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.addViewInner(ViewGroup.java:1994)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.addViewInLayout(ViewGroup.java:1958)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.addViewInLayout(ViewGroup.java:1939)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.support.v4.view.ViewPager.addView(ViewPager.java:917)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.addView(ViewGroup.java:1828)
02-22 12:22:50.256: E/AndroidRuntime(384): at us.tagverse.pagertest.MasterActivity$PAdapter.instantiateItem(MasterActivity.java:518)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.support.v4.view.PagerAdapter.instantiateItem(PagerAdapter.java:110)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:649)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.support.v4.view.ViewPager.populate(ViewPager.java:783)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1016)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.View.measure(View.java:8313)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1017)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.widget.LinearLayout.measureVertical(LinearLayout.java:386)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.widget.LinearLayout.onMeasure(LinearLayout.java:309)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.View.measure(View.java:8313)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.View.measure(View.java:8313)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.View.measure(View.java:8313)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewRoot.performTraversals(ViewRoot.java:839)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewRoot.handleMessage(ViewRoot.java:1859)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.os.Handler.dispatchMessage(Handler.java:99)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.os.Looper.loop(Looper.java:123)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.app.ActivityThread.main(ActivityThread.java:3683)
02-22 12:22:50.256: E/AndroidRuntime(384): at java.lang.reflect.Method.invokeNative(Native Method)
02-22 12:22:50.256: E/AndroidRuntime(384): at java.lang.reflect.Method.invoke(Method.java:507)
02-22 12:22:50.256: E/AndroidRuntime(384): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-22 12:22:50.256: E/AndroidRuntime(384): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-22 12:22:50.256: E/AndroidRuntime(384): at dalvik.system.NativeStart.main(Native Method)
Należy pamiętać, że przyczyną jest java.lang.IndexOutOfBoundsException: index=1 count=0
. Oznaczałoby to, że liczba stron/pozycji wynosi 0, a indeks, który żądam, to 1. Żadna z tych rzeczy nie jest prawdziwa. Oto jak wzywam moje ViewPager i prosząc podanej strony:
ViewPager pager = (ViewPager) findViewById(R.id.ma_viewcontainer);
PAdapter adapter = new PAdapter();
pager.setAdapter(adapter);
pager.setCurrentItem(2);
Zauważ, że ta rozmowa nie daje żadnych błędów i poprawnie ustawia bieżący element do pozycji środkowej (indeks 1):
ViewPager pager = (ViewPager) findViewById(R.id.ma_viewcontainer);
PAdapter adapter = new PAdapter();
pager.setAdapter(adapter);
pager.setCurrentItem(1);
Mam 3 pozycje w widoku pager. Oto moja pełna klasa PAdapter, która rozszerza klasę PagerAdapter:
private class PAdapter extends PagerAdapter implements TitleProvider {
private int COUNT = 3;
private static final int SETTINGS_ACTIVITY = 0;
private static final int MAIN_ACTIVITY = 1;
private static final int FRIEND_LIST_ACTIVITY = 2;
@Override
public int getCount() {
return COUNT;
}
@Override
public Object instantiateItem(View collection, int position) {
LinearLayout layout = new LinearLayout(getApplicationContext());
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
switch(position) {
case MAIN_ACTIVITY :
layout = (LinearLayout) inflater.inflate(R.layout.main, null, false);
initMainLayout(layout);
break;
case SETTINGS_ACTIVITY :
layout = (LinearLayout) inflater.inflate(R.layout.settings, null, false);
initSettingsLayout(layout);
break;
case FRIEND_LIST_ACTIVITY :
layout = (LinearLayout) inflater.inflate(R.layout.friend_list, null, false);
initFriendListLayout(layout);
break;
}
((ViewPager)collection).addView(layout, position);
return layout;
}
@Override
public void destroyItem(View collection, int position, Object view) {
((ViewPager)collection).removeView((LinearLayout)view);
}
@Override
public boolean isViewFromObject(View v, Object o) {
return v == (LinearLayout)o;
}
@Override
public void finishUpdate(View arg0) {
//no need
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
//no need
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public void startUpdate(View arg0) {
//no need
}
@Override
public String getTitle(int position) {
Resources res = getApplicationContext().getResources();
switch(position) {
case MAIN_ACTIVITY :
return res.getString(R.string.app_name);
case SETTINGS_ACTIVITY :
return res.getString(R.string.settings);
case FRIEND_LIST_ACTIVITY :
return res.getString(R.string.friend_list);
default :
return null;
}
}
}
Linia ((ViewPager)collection).addView(layout, position);
powoduje awarię.
Jak widać, trzy elementy. Używanie setCurrentItem() z parametrem 0 lub 1 działa dobrze, ale 2 powoduje ten dziwny błąd. Nie mam pomysłów na rozwiązanie ... Niestety ViewPager znajduje się w niezbadanych wodach Androida. Jeśli ktokolwiek ma pewien wgląd w to, jak rozwiązać ten problem, będzie to bardzo cenne. Dzięki!
EDIT: Zgodnie z sugestią Shereef, w Próbowałem zalogowaniu liczyć dziecko poprzez collection.getChildCount() i mam następujący wynik:
02-22 15:20:42.274: E/children count(645): count: 0
02-22 15:20:42.454: E/children count(645): count: 1
02-22 15:20:42.594: E/children count(645): count: 2
To jest ciekawe. To, co mi to mówi, to tworzenie pustego PagerAdaptera i dodawanie ich pojedynczo. instantiateItem()
jest wywoływany 3 razy dla trzech widocznych widoków (środek, lewo i prawo). Więc dodałem poniższy fragment kodu wewnątrz metody instantiateItem()
:
if(((ViewPager)collection).getChildCount() == 2) {
((ViewPager)collection).setCurrentItem(2);
}
tak tylko wtedy, gdy liczba jest ustalona będzie 2 będzie to ustawić stronę do 2 (jest to hacky rozwiązanie, które nie w pełni rozwiązać problem , ale warto było spróbować). Mam podobny stos błędów, który wskazywał najpierw na linię: ((ViewPager)collection).setCurrentItem(2);
, a następnie ((ViewPager)collection).addView(layout, position);
.
Mam nadzieję, że pomoże to w pewnym stopniu.
jeśli (kolekcja (ViewPager)) .getChildCount() == 2) { (kolekcja (ViewPager)) .setCurrentItem (2); } oznacza to, że widok zostanie utworzony i wprowadzony do kolekcji tylko w takim przypadku, inne będą przerysowane od podstaw, w związku z tym stracisz optymalizację widoku strony, aby odtworzyć widoki, a nie przerysować je od podstaw. –