数组超出ViewPager的范围

时间:2017-12-18 21:04:39

标签: android arrays android-viewpager

我在ViewPager类中得到一个超出范围的数组异常,但我不确定为什么。

在快速浏览视图寻呼机时似乎会发生这种情况,看起来保存项目的内部数组是空的,因为它试图抓住索引0。

这是堆栈跟踪

java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
   at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
   at java.util.ArrayList.get(ArrayList.java:308)
   at android.support.v4.view.ViewPager.performDrag(ViewPager.java:2343)
   at android.support.v4.view.ViewPager.onTouchEvent(ViewPager.java:2262)
   at android.view.View.dispatchTouchEvent(View.java:8471)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2399)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2092)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
   at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2405)
   at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2106)
   at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2369)
   at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1719)
   at android.app.Activity.dispatchTouchEvent(Activity.java:2742)
   at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2330)
   at android.view.View.dispatchPointerEvent(View.java:8666)
   at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4123)
   at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3989)
   at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
   at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
   at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
   at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3680)
   at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
   at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3737)
   at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
   at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3597)
   at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3563)
   at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3571)
   at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3544)
   at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5807)
   at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5781)
   at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5752)
   at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5897)
   at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
   at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.ja

以下是设置视图页面和设置适配器的代码。在这种情况下,我们遵循isTablet路径。

private void initializePaging() {

    if (resources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
        menuGridSize = 3;
    }
    else {
        menuGridSize = 4;
    }

    if (mMenus != null) {
        if (Utility.isTabletDevice(getActivity())) {
            int count = mMenus.size() / menuGridSize;
            int extras = mMenus.size() % menuGridSize;

            int activatedIndicator = 0;
            if (pageIndicators != null) {
                for (int i = 0; i < pageIndicators.size(); i++) {
                    if (pageIndicators.get(i).isActivated()) {
                        activatedIndicator = i;
                        break;
                    }
                }
            }

            pageIndicatorLayout.removeAllViews();
            pageIndicators = new ArrayList<>();
            for (int i = 0; i < count; i++) {
                ImageView temp = new ImageView(context);
                temp.setPadding(10, 10, 10, 10);
                temp.setImageDrawable(mTheme.pageIndicatorSelector(context));
                pageIndicatorLayout.addView(temp);
                pageIndicators.add(temp);
            }

            if (extras != 0) {
                ImageView temp = new ImageView(context);
                temp.setPadding(10, 10, 10, 10);
                temp.setImageDrawable(mTheme.pageIndicatorSelector(context));
                pageIndicatorLayout.addView(temp);
                pageIndicators.add(temp);
            }
            pageIndicators.get(activatedIndicator).setActivated(true);

            if (pageIndicators.size() <= 1) {
                pageIndicatorLayout.setVisibility(View.GONE);
            }

            if (adapter == null) {
                adapter = new MainMenuPagerAdapter(getFragmentManager(), mMenus, menuGridSize, changeFragmentListener);
            }
            else {
                adapter.setGridSize(menuGridSize);
            }

            pager.setAdapter(adapter);
            pager.setOnPageChangeListener(new OnPageChangeListener() {

                public void onPageScrollStateChanged(int arg0) {

                }

                public void onPageScrolled(int arg0, float arg1, int arg2) {

                }

                public void onPageSelected(int arg0) {

                    for (int i = 0; i < pageIndicators.size(); i++) {
                        if (i == arg0) {
                            pageIndicators.get(i).setActivated(true);
                        }
                        else {
                            pageIndicators.get(i).setActivated(false);
                        }
                    }
                }
            });

            adapter.notifyDataSetChanged();
            progress.setVisibility(View.GONE);
            pager.setVisibility(View.VISIBLE);
        }
        else {
            menuList.setAdapter(new MainMenuAdapter(getActivity(), mMenus));
            progress.setVisibility(View.GONE);
            menuList.setVisibility(View.VISIBLE);
        }

        view.invalidate();
    }
}

以下是适配器的代码

public class MainMenuPagerAdapter extends FragmentStatePagerAdapter {

public static final String TAG = "MainMenuPagerAdapter";

private List<GenericMenu> menus = new ArrayList<>();
private int gridSize;
private ChangeFragmentListener changeFragmentListener;

public MainMenuPagerAdapter(FragmentManager fragmentManager, List<GenericMenu> menus, int gridSize, final ChangeFragmentListener changeFragmentListener) {

    super(fragmentManager);
    this.menus = menus;
    this.gridSize = gridSize;
    this.changeFragmentListener = changeFragmentListener;
}

public void setGridSize(int gridSize) {

    this.gridSize = gridSize;
}

@Override
public Fragment getItem(int position) {

    int subListStart = position * gridSize;
    int subListEnd = position * gridSize + gridSize;

    if (subListEnd >= menus.size()) {
        subListEnd = menus.size();
    }

    // find the menus for this page
    ArrayList<GenericMenu> subList = new ArrayList<GenericMenu>();
    subList.addAll(menus.subList(subListStart, subListEnd));

    Bundle bundle = new Bundle();
    bundle.putParcelableArrayList("menus", subList);
    bundle.putInt("columns", gridSize);
    MainMenuPageFragment fragment = new MainMenuPageFragment();
    fragment.setArguments(bundle);
    fragment.setChangeFragmentListener(new ChangeFragmentListener() {

        public void changeFragment(BaseIceFragment fragment, String titleText, String image, float size) {

            if (changeFragmentListener != null) {
                changeFragmentListener.changeFragment(fragment, titleText, image, size);
            }
        }
    });

    return fragment;
}

@Override
public int getCount() {

    int count = menus.size() / gridSize;
    count += menus.size() % gridSize > 0 ? 1 : 0;

    return count;
}

@Override
public int getItemPosition(Object object) {

    return POSITION_NONE;
}

@Override
public Parcelable saveState() {

    // Do nothing
    return null;
}
}

1 个答案:

答案 0 :(得分:0)

此问题可能是由源文件引起的。在ViewPager中,setAdaper()将mItems设置为null。拖动ViewPager时,调用setAdapter时会出现此问题。你可以看到performDrag()方法mItems.get(0)不要添加大小检查。

SOLUTION:使用notifyDataChanged刷新数据而不是setAdapter:

if(mAdapter == null){
    mAdapter = new CarInfoViewPagerAdapter(views);
} else {
    mAdapter.setViews(views);
}
if(mViewPager.getAdapter() == null){
    mViewPager.setAdapter(mAdapter);
} else {
    mAdapter.notifyDataSetChanged();
}
  • 由于你没有提供代码,我只是编写了名称 - mItems,mAdapter和mViewPager,但我确信你能够联系。希望这会有所帮助。