You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ViewPager滑动切换卡片时IndexOutOfBoundsException异常排查

问题现象

ViewPager滑动切换卡片时触发崩溃,捕获到如下异常:

java.lang.IndexOutOfBoundsException: index=5 count=4

Logcat定位异常关联点为自定义PagerAdapter的instantiateItem方法中container.addView(view, position)代码行,初步怀疑数据源ArrayList存在问题。

根因定位

核心崩溃原因是错误将数据源的position参数作为ViewGroup的子View插入索引传入addView方法:

  • container.addView(view, index)方法要求传入的index必须在0 ~ container.getChildCount()范围内,这个index是View在容器内部子View列表的位置,和数据源的总长度、数据源位置没有直接关系。
  • ViewPager默认只会缓存当前页+左右相邻页共3个左右的子View,滑动过程中会动态回收、创建View,容器内实际存在的子View数量远小于数据源总长度。当滑动到position=5的卡片时,容器内仅存在4个子View(对应日志里的count=4),此时要求把新View插入到index=5的位置,直接触发索引越界。

除此之外代码里还有两个隐藏问题:

  • 贴出的DashboardFlavorModel类缺失全参构造方法、count字段的getter/setter,和初始化时传3个参数实例化Model的逻辑不匹配
  • 加减按钮的点击事件捕获了instantiateItem时的初始count值,点击修改后不会同步刷新界面显示的数量,属于功能逻辑bug
修复方案
  • 修正addView调用:删除传入的position参数,直接调用container.addView(view)即可,ViewPager内部会自行管理子View的排列顺序,不需要手动指定插入位置
  • 补全Model类缺失的方法
  • 修复加减按钮的计数逻辑,点击时实时读取Model的最新count值,修改后同步刷新UI

核心修改代码

  1. 修正instantiateItem方法中的addView逻辑与按钮点击逻辑
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
    View view = LayoutInflater.from(context).inflate(R.layout.flavor_item, container, false);
    ImageView imageIv = view.findViewById(R.id.imageIv);
    TextView flavorTv = view.findViewById(R.id.flavorTv);
    TextView quantityTv = view.findViewById(R.id.quantityTv);
    ImageButton minusbutton = view.findViewById(R.id.minusbutton);
    ImageButton plusbutton = view.findViewById(R.id.plusbutton);

    DashboardFlavorModel model = modelArrayList.get(position);
    imageIv.setImageResource(model.getImage());
    flavorTv.setText(model.getTitle());
    quantityTv.setText(String.valueOf(model.getCount()));

    minusbutton.setOnClickListener(v -> {
        int currentCount = model.getCount();
        if (currentCount > 0) {
            model.setCount(currentCount - 1);
            quantityTv.setText(String.valueOf(model.getCount()));
        } else {
            Snackbar.make(v, "You cannot have less than 0 QTY", Snackbar.LENGTH_LONG).show();
        }
    });

    plusbutton.setOnClickListener(v -> {
        int currentCount = model.getCount();
        model.setCount(currentCount + 1);
        quantityTv.setText(String.valueOf(model.getCount()));
    });

    // 修复:删除position参数,不手动指定插入位置
    container.addView(view);
    return view;
}
  1. 补全DashboardFlavorModel类
public class DashboardFlavorModel {
    String title;
    int image,count;

    // 补全全参构造
    public DashboardFlavorModel(String title, int image, int count) {
        this.title = title;
        this.image = image;
        this.count = count;
    }

    // 补全count字段的getter/setter
    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getImage() {
        return image;
    }

    public void setImage(int image) {
        this.image = image;
    }
}
验证说明

修改后ViewPager滑动过程中创建子View时,会默认将新View添加到容器子列表末尾,由ViewPager内部自行处理布局位置,不会再出现插入索引超出容器子View数量的越界问题;加减按钮点击后也会实时刷新显示的数量值,功能正常。

内容的提问来源于stack exchange,提问作者Zhe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 00:47:06