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

BottomSheet结合ViewPager出现ArrayIndexOutOfBoundsException异常

解决ViewPager滑动时的ArrayIndexOutOfBoundsException异常

我看到你在开发带ViewPager标签栏的BottomSheet时遇到了滑动几次就抛出数组越界的问题,咱们直接从错误根源和解决方案说起:

问题根源分析

从Logcat的报错信息可以定位到异常发生在Bottom_Viewpager_Fragment.onCreateView方法的第47行,也就是遍历liquerdata数组的循环里。

核心问题在于你把i和j定义成了Fragment的成员变量,而非循环内部的局部变量:

  • ViewPager默认会预加载相邻的Fragment,当你滑动三四次后,新的Fragment实例被创建时,i和j并没有被重置为0,而是继承了之前Fragment实例中已经累加后的数值(比如第一次循环后i和j会变成5)。
  • 而你的liquertype和price数组长度都是5,最大索引为4,这时候再执行liquertype[i]或price[j],就会直接触发ArrayIndexOutOfBoundsException。

解决方案

有两种简单的修复方式,推荐第一种:

方法1:将i、j改为循环局部变量(推荐)

把i和j移到onCreateView方法内部,作为循环的局部变量,这样每次创建Fragment时都会重新初始化:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.fragment_bottom__viewpager_, container, false);
    bottle_checked1 = (AppCompatImageView)view.findViewById(R.id.bottle_checked1);
    bottle_text1 = (CustomTextView)view.findViewById(R.id.bottle_text1);
    beerprice1 = (CustomTextView)view.findViewById(R.id.beerprice1);
    liquer_data_providers = new ArrayList<>();
    
    // 将i、j改为局部变量,每次onCreateView都会重新初始化
    int i = 0;
    int j = 0;
    for(String data:liquerdata) {
        liquer_data_provider = new Liquer_Data_Provider(liquertype[i],data,price[j]);
        i++;
        j++;
        liquer_data_providers.add(liquer_data_provider);
        bottle_text1.setText(liquer_data_provider.getGlass_name());
        beerprice1.setText(Integer.toString(liquer_data_provider.getPrice()));
    }
    bottle_text1.setOnClickListener(this);
    return view;
}

方法2:每次onCreateView时重置成员变量

如果一定要保留i、j作为成员变量,在进入onCreateView时手动把它们重置为0:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.fragment_bottom__viewpager_, container, false);
    bottle_checked1 = (AppCompatImageView)view.findViewById(R.id.bottle_checked1);
    bottle_text1 = (CustomTextView)view.findViewById(R.id.bottle_text1);
    beerprice1 = (CustomTextView)view.findViewById(R.id.beerprice1);
    liquer_data_providers = new ArrayList<>();
    
    // 重置成员变量i和j为0
    i = 0;
    j = 0;
    for(String data:liquerdata) {
        liquer_data_provider = new Liquer_Data_Provider(liquertype[i],data,price[j]);
        i++;
        j++;
        liquer_data_providers.add(liquer_data_provider);
        bottle_text1.setText(liquer_data_provider.getGlass_name());
        beerprice1.setText(Integer.toString(liquer_data_provider.getPrice()));
    }
    bottle_text1.setOnClickListener(this);
    return view;
}

额外小提示

你在循环里每次都给bottle_text1和beerprice1设置文本,最终只会显示最后一条数据的内容,这大概率不是你想要的效果。如果要展示所有的酒类数据,建议用RecyclerView或ListView来渲染整个liquer_data_providers列表,而不是重复覆盖同一个TextView的内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:56:49