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

如何在ViewPager中设置多View?解决数组越界异常问题

修复ViewPager每页显示3个Item的PagerAdapter问题

看了你的代码,问题出在索引计算逻辑完全混乱——你一开始把页面位置position乘以2,这和每页3个Item的需求完全不匹配,后面的越界判断(比如position==getRealCount()时取position-1、position-2)也逻辑错误,直接导致了IndexOutOfBoundException。

我帮你重新梳理了逻辑,核心思路是:

  • 每个页面的起始索引是 页面位置 * 每页数量(也就是position * 3)
  • 依次处理当前页面的3个Item,每个Item的索引是startIndex、startIndex+1、startIndex+2
  • 对每个索引,判断是否小于数据总长度,符合条件就填充数据并显示,否则隐藏该Item

以下是修正后的完整代码:

public class SummaryViewPagerAdapter extends PagerAdapter { 
    private List<SummaryModel> mSummaryModelList; 
    private Context context; 
    private LayoutInflater inflater; 

    public SummaryViewPagerAdapter(Context context, List<SummaryModel> summaryModels ) { 
        this.mSummaryModelList = summaryModels; 
        this.context = context; 
        this.inflater = LayoutInflater.from(context); // 提前初始化LayoutInflater,避免重复获取
    } 

    @Override 
    public int getCount() { 
        // 计算总页数:向上取整,比如5条数据就是2页
        return (mSummaryModelList.size() + 3 - 1) / 3; 
    } 

    @Override 
    public boolean isViewFromObject(View view, Object object) { 
        return view == object; 
    } 

    private void populateTextView(TextView statusTxt, TextView statusCount, 
                                 String status, String color, RelativeLayout layout, String count) { 
        statusTxt.setText(status); 
        statusCount.setText(count); 
        layout.setBackgroundColor(Color.parseColor(color)); 
        // 填充数据后直接设置可见,不用重复写
        statusTxt.setVisibility(View.VISIBLE); 
        statusCount.setVisibility(View.VISIBLE); 
        layout.setVisibility(View.VISIBLE); 
    } 

    @Override 
    public Object instantiateItem(ViewGroup container, int position) { 
        View itemView = inflater.inflate(R.layout.summary_viewholder, container, false); 

        // 计算当前页面的起始索引
        int startIndex = position * 3; 
        int realCount = getRealCount(); 

        // 处理第一个Item
        TextView statusTxt1 = itemView.findViewById(R.id.txt_1); 
        TextView countTxt1 = itemView.findViewById(R.id.count_1); 
        RelativeLayout rl1 = itemView.findViewById(R.id.rl_1); 
        if (startIndex < realCount) { 
            SummaryModel model = mSummaryModelList.get(startIndex); 
            populateTextView(statusTxt1, countTxt1, model.getName(), model.getColorCode(), rl1, String.valueOf(model.getCount())); 
        } else { 
            statusTxt1.setVisibility(View.INVISIBLE); 
            countTxt1.setVisibility(View.INVISIBLE); 
            rl1.setVisibility(View.INVISIBLE); 
        } 

        // 处理第二个Item
        TextView statusTxt2 = itemView.findViewById(R.id.txt_2); 
        TextView countTxt2 = itemView.findViewById(R.id.count_2); 
        RelativeLayout rl2 = itemView.findViewById(R.id.rl_2); 
        int secondIndex = startIndex + 1; 
        if (secondIndex < realCount) { 
            SummaryModel model = mSummaryModelList.get(secondIndex); 
            populateTextView(statusTxt2, countTxt2, model.getName(), model.getColorCode(), rl2, String.valueOf(model.getCount())); 
        } else { 
            statusTxt2.setVisibility(View.INVISIBLE); 
            countTxt2.setVisibility(View.INVISIBLE); 
            rl2.setVisibility(View.INVISIBLE); 
        } 

        // 处理第三个Item
        TextView statusTxt3 = itemView.findViewById(R.id.txt_3); 
        TextView countTxt3 = itemView.findViewById(R.id.count_3); 
        RelativeLayout rl3 = itemView.findViewById(R.id.rl_3); 
        int thirdIndex = startIndex + 2; 
        if (thirdIndex < realCount) { 
            SummaryModel model = mSummaryModelList.get(thirdIndex); 
            populateTextView(statusTxt3, countTxt3, model.getName(), model.getColorCode(), rl3, String.valueOf(model.getCount())); 
        } else { 
            statusTxt3.setVisibility(View.INVISIBLE); 
            countTxt3.setVisibility(View.INVISIBLE); 
            rl3.setVisibility(View.INVISIBLE); 
        } 

        container.addView(itemView); 
        return itemView; 
    } 

    @Override 
    public void destroyItem(ViewGroup container, int position, Object object) { 
        container.removeView((View) object); // 这里改成View更通用,避免强转LinearLayout报错
    } 

    private int getRealCount() { 
        return mSummaryModelList.size(); 
    } 
}

关键改进点:

  • 提前初始化LayoutInflater,避免在instantiateItem中重复获取系统服务,优化性能
  • 用startIndex = position * 3计算页面起始索引,逻辑清晰,不会越界
  • 每个Item的索引单独计算(startIndex、startIndex+1、startIndex+2),判断是否小于数据总数,逻辑简单直接
  • 修复了destroyItem中的强转问题,改成View更通用
  • 简化了populateTextView方法,填充数据后直接设置可见,减少重复代码

这样修改后,当数据长度为5时:

  • 第0页(第一页)的索引是0、1、2,显示3个Item
  • 第1页(第二页)的索引是3、4、5,其中5超出数据长度(总数5,索引最大是4),所以第三个Item隐藏,显示前2个,完全符合你的需求。

内容的提问来源于stack exchange,提问作者M.Yogeshwaran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:47:36