Ho un ViewPager con tre elementi. Sto cercando di impostare ViewPager per visualizzare la pagina più a destra (che sarebbe il 2 ° elemento). Questo sta restituendo un'eccezione IndexOutOfBounds, anche se so che l'indice dovrebbe essere in limiti. Qui è lo stack esatto:ViewPager Android che lancia l'eccezione IndexOutOfBounds quando si imposta l'elemento/pagina corrente
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)
Nota che la causa è java.lang.IndexOutOfBoundsException: index=1 count=0
. Ciò implicherebbe che il conteggio delle pagine/elementi sia 0 e l'indice che sto richiedendo sia 1. Nessuna di queste cose è vera. Ecco come io chiamo il mio ViewPager e richiede la pagina data:
ViewPager pager = (ViewPager) findViewById(R.id.ma_viewcontainer);
PAdapter adapter = new PAdapter();
pager.setAdapter(adapter);
pager.setCurrentItem(2);
Si noti che questa chiamata non dà alcun errore, e imposta correttamente l'elemento corrente alla voce di mezzo (indice 1):
ViewPager pager = (ViewPager) findViewById(R.id.ma_viewcontainer);
PAdapter adapter = new PAdapter();
pager.setAdapter(adapter);
pager.setCurrentItem(1);
Ho un conteggio di 3 elementi nel pager della vista. Qui è la mia classe PAdapter pieno, che estende la classe 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;
}
}
}
La linea ((ViewPager)collection).addView(layout, position);
causa l'arresto.
Come potete vedere, tre elementi. L'utilizzo di setCurrentItem() con un parametro 0 o 1 funziona bene, ma 2 causa questo strano errore. Ho esaurito le idee per risolverlo ... sfortunatamente ViewPager risiede in alcune acque inesplorate di Android a quanto pare. Se qualcuno ha qualche idea su come risolvere questo sarebbe molto apprezzato. Grazie!
EDIT: Come da suggerimento di Shereef, ho provato registrando contare il bambino via collection.getChildCount() e ha ottenuto il seguente risultato:
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
Questo è interessante. Ciò che questo mi dice è che sta creando un PagerAdapter vuoto e aggiungendoli uno alla volta. instantiateItem()
viene chiamato 3 volte per le tre viste visibili (centro, sinistra e destra). Così ho aggiunto questo blocco di codice all'interno del metodo instantiateItem()
:
if(((ViewPager)collection).getChildCount() == 2) {
((ViewPager)collection).setCurrentItem(2);
}
Quindi, solo se il conteggio è stabilita per essere 2 sarà vero impostare la pagina 2 (questa è una soluzione hacky che non affrontare pienamente il problema , ma valeva la pena provare). Ho ottenuto uno stack di errore simile che indicava prima la riga: ((ViewPager)collection).setCurrentItem(2);
, quindi ((ViewPager)collection).addView(layout, position);
.
Spero che questo aiuti a dare qualche idea.
if ((raccolta (ViewPager)) .getChildCount() == 2) { (raccolta (ViewPager)) .setCurrentItem (2); } questo significa che la vista verrà creata e inserita nella raccolta solo in tal caso, altri saperi verranno ridisegnati da zero, quindi si perde l'ottimizzazione del viewpager per riciclare le viste anziché ridisegnarle da zero –