PagerAdapter中destroyItem遇到IndexOutOfBoundsException

发布于 2022-09-04 00:27:12 字数 2511 浏览 21 评论 0

写了一个无限循环的ViewPager,原理是在最左和最右各增加一个View,用于滑动。但是跑Monkey的时候爆出:

CRASH: com.wzy.test(pid 11400)
// Short Msg: java.lang.IndexOutOfBoundsException保存 
// Long Msg: java.lang.IndexOutOfBoundsException: Invalid index 3, size is 3
// Build Changelist: 1475158271
// Build Time: 1475158954000
// java.lang.IndexOutOfBoundsException: Invalid index 3, size is 3
//     at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:260)
//     at java.util.ArrayList.get(ArrayList.java:313)
//     at com.wzy.test.widget.MarqueeContainer$MarqueePagerAdapter.destroyItem(MarqueeContainer.java:230)
//     at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:474)
//     at com.wzy.test.widget.MarqueeContainer.showMarquee(MarqueeContainer.java:169)
//     at com.wzy.test.widget.MarqueeContainer.setImagesUrl(MarqueeContainer.java:76)
//     at com.wzy.test.activity.DetailActivity$1.handleMessage(DetailActivity.java:62)
//     at android.os.Handler.dispatchMessage(Handler.java:111)
//     at android.os.Looper.loop(Looper.java:205)
//     at android.app.ActivityThread.main(ActivityThread.java:5811)
//     at java.lang.reflect.Method.invoke(Native Method)
//     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:806)
//     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)

很奇怪,理论上一共就有三个item,destoryItem的position不应该为3.

实现的PagerAdapter:

public class MarqueePagerAdapter extends PagerAdapter {

    /**
     * 获取要滑动控件的数量.我们的自定义控件用来实现图片的滑动,因此这里就应该是展示的图片的数量.
     */
    @Override
    public int getCount() {
        return mDisplayViewList == null ? 0 : mDisplayViewList.size();
    }

    /**
     * 来判断显示的是否是同一张图片,我们直接将两个参数进行比较即可.
     */
    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    /**
     * 当要显示的图片可以进行缓存的时候,会调用这个方法进行显示图片的初始化.
     * 我们将要显示的ImageView添加到container中,然后将该ImageView返回即可.
     */
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(mDisplayViewList.get(position));
        return mDisplayViewList.get(position);
    }

    /**
     * ViewPager默认只缓存三张要显示的图片,如果滑动的图片超过了缓存的范围,就会调用这个方法将图片移除
     */
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(mDisplayViewList.get(position));
    }
}

求指导一下,大家是怎么解决这个问题的?(ps:没有调用过notifyDataSetChanged方法)。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我要还你自由 2022-09-11 00:27:12

问题就是数组越界了
在destroyItem方法中打个log看看mDisplayViewList.size()实际数据num,猜测在代码其他位置你的mDisplayViewList数据发生了变化,另外mDisplayViewList是什么具体数据呢?
解决方法供参考

@Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        if(position > mDisplayViewList.size() - 1)return;
        container.removeView(mDisplayViewList.get(position));
    }
椒妓 2022-09-11 00:27:12

destroyItem 方法应该删除传过来的 object 对象,这个是销毁你已经添加到页面上的元素,而不是在方法里再次删除你已经删除的对象。

    override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
        container.removeView(`object` as View?)
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文