Android ViewPager бросает исключение IndexOutOfBounds при настройке текущего элемента/страницы - программирование
Подтвердить что ты не робот

Android ViewPager бросает исключение IndexOutOfBounds при настройке текущего элемента/страницы

У меня есть ViewPager с тремя элементами. Я пытаюсь установить ViewPager для просмотра страницы, наиболее удаленной справа (которая будет вторым элементом). Это возвращает исключение IndexOutOfBounds, хотя я знаю, что индекс должен быть в границах. Вот точный стек:

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)

Обратите внимание, что причиной является java.lang.IndexOutOfBoundsException: index=1 count=0. Это означало бы, что количество страниц/элементов равно 0, а индекс, который я запрашиваю, равен 1. Ни одна из этих вещей не верна. Вот как я вызываю свой ViewPager и запрашиваю данную страницу:

ViewPager pager = (ViewPager) findViewById(R.id.ma_viewcontainer);
PAdapter adapter = new PAdapter();
pager.setAdapter(adapter);
pager.setCurrentItem(2);

Обратите внимание, что этот вызов не дает никакой ошибки и правильно устанавливает текущий элемент в средний элемент (индекс 1):

ViewPager pager = (ViewPager) findViewById(R.id.ma_viewcontainer);
PAdapter adapter = new PAdapter();
pager.setAdapter(adapter);
pager.setCurrentItem(1);

У меня есть счет из 3 элементов в представлении пейджера. Вот мой полный класс PAdapter, который расширяет класс 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;
        }
    }
}

Линия ((ViewPager)collection).addView(layout, position); вызывает сбой.

Как вы можете видеть, три элемента. Использование setCurrentItem() с параметром 0 или 1 работает просто отлично, но 2 вызывает эту странную ошибку. У меня кончились идеи, чтобы решить эту проблему... К сожалению, ViewPager находится в некоторых неизведанных водах Android. Если у кого-то есть представление о том, как его решить, это будет очень признательно. Спасибо!

EDIT: в соответствии с предложением Shereef я попытался зарегистрировать счетчик child через collection.getChildCount() и получил следующий результат:

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

Это интересно. Это говорит о том, что он создает пустой PagerAdapter и добавляет их по одному. instantiateItem() вызывается 3 раза для трех видимых видов (в центре, влево и вправо). Поэтому я добавил этот блок кода в метод instantiateItem():

if(((ViewPager)collection).getChildCount() ==  2) {
    ((ViewPager)collection).setCurrentItem(2);
}

Итак, только если счетчик установлен равным 2, он установит страницу в 2 (это хакерское решение, которое не полностью решает проблему, но стоило попробовать). У меня есть аналогичный стек ошибок, который указал сначала на строку: ((ViewPager)collection).setCurrentItem(2);, затем ((ViewPager)collection).addView(layout, position);.

Надеюсь, что это поможет дать некоторое представление.

4b9b3361

Ответ 1

Я не думаю, что вы можете просто сделать ((ViewPager)collection).addView(layout, position). Это зависит от предела вашей страницы, который по умолчанию равен 1, я считаю. Я предполагаю, что вы используете только 3 вида, поэтому вы можете сделать что-то вроде viewPager.setOffscreenPageLimit(3); в своем `onCreate (или везде, где вы разместили свой вызов), чтобы каждый обновляемый просмотр не обновлялся каждый раз, когда вы его оставляете.

В нескольких учебниках вы увидите, что ((ViewPager) collection).addView(view, 0); используется в instantiateItem(). За последние несколько недель я немного поработал с ViewPagers и использовал 0 в качестве позиции -all- время, похоже, работает нормально.

Ответ 2

Я вижу журнал сбоев, я вижу, что он падает в экземпляре элемента. Я не знаю, какая строка именно потому, что у меня нет номеров строк

Но если бы я был игроком ставок, я бы поспорил, что:

  ((ViewPager)collection).addView(layout, position);

Сбой при попытке добавить вид в позицию 1, пока в коллекции нет страниц Возможно, проверьте collection.getchildcount() (возможно, имя метода неверно) и вставьте в max (position, count)

Замените позицию следующим образом:

count > position ? position : count

ИЗМЕНИТЬ:

((ViewPager)collection).addView(layout, ((ViewPager)collection).getChildCount() > position ? position : ((ViewPager)collection).getChildCount())

p.s. Проводка с моего телефона извиняется за ужасное форматирование

Обратите внимание на

 02-22 12:22:50.256: E/AndroidRuntime(384): at us.tagverse.pagertest.MasterActivity$PAdapter.instantiat 

MasterActivity.java:518

Число в конце строки, которую я скопировал, и выяснить, какая из них это тогда, и только тогда вы узнаете, какая строка получила авария

EDIT: P.S. о вашем решении

Я думаю, что ваше решение только устанавливает текущий элемент после того, как три страницы были созданы экземпляром элемента, но моя строка заставит его работать, даже если они не получили экземпляр.