Android:通过REST API为TabLayout加载分类名称及报错解决
解决方案:FragmentTabLayout + ViewPager 加载API数据的两个问题修复
问题2:IndexOutOfBoundsException(列表为空时调用get(1))
原因分析
报错触发在ViewPagerAdapter.getPageTitle()方法中:当shopmenu列表还未从API加载到数据(size=0)时,代码尝试调用get(1)获取元素,直接导致数组越界。本质是ViewPager的Adapter在异步数据加载完成前就已绑定到TabLayout/ViewPager,此时列表为空但Adapter仍在尝试访问不存在的元素。
修复步骤
给Adapter添加边界安全判断
在getPageTitle()中先校验列表状态,非法场景返回默认值,避免直接越界访问:@Override public CharSequence getPageTitle(int position) { // 先判断列表是否为空、索引是否合法 if (shopmenu == null || shopmenu.size() <= position) { return "分类"; // 或空字符串"",根据需求调整 } // 合法场景返回对应分类名称 return shopmenu.get(position).getCid(); }规范异步数据加载流程
- 初始化时先创建空列表与Adapter,提前绑定到ViewPager/TabLayout;
- API请求成功后,更新列表并通知Adapter刷新UI:
private ArrayList<ShopMenu> shopmenu = new ArrayList<>(); private ViewPagerAdapter adapter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 初始化空Adapter并绑定 adapter = new ViewPagerAdapter(getChildFragmentManager()); viewPager.setAdapter(adapter); tabLayout.setupWithViewPager(viewPager); // 发起API请求 loadRemoteMenuData(); } // API请求成功后的回调方法示例 private void onMenuDataLoaded(ArrayList<ShopMenu> remoteData) { shopmenu.clear(); shopmenu.addAll(remoteData); adapter.notifyDataSetChanged(); // 通知Adapter数据更新 }移除硬编码索引
禁止直接使用get(1)这类固定索引,必须用position参数对应列表的动态位置,保证Tab数量与列表元素数量一一对应。
问题1:获取JSON中cid字段失败
原因分析
getResources().getString(int resId)的作用是根据资源ID(如R.string.app_name)读取res/values目录下的字符串资源,但Menu1.cid是从JSON解析得到的字符串内容,并非资源ID,用这个方法会直接导致逻辑错误或崩溃。
修复步骤
直接返回实体类中的cid字段即可,无需调用getResources().getString():
// 错误写法 // return (String) getResources().getString(Menu1.cid); // 正确写法 return shopmenu.get(position).getCid();
如果你的ShopMenu实体类还没有对应getter方法,需要补充:
public class ShopMenu { private String cid; // 对应JSON中的cid字段 // 构造方法、其他字段与setter方法... public String getCid() { return cid; } }
额外注意事项
- API请求必须放在子线程执行,避免阻塞主线程;
- 可添加加载状态(如ProgressBar),在数据加载完成前显示,提升用户体验;
- 处理API请求失败的场景,比如显示错误提示,避免列表长期为空导致Tab显示默认标题。
内容的提问来源于stack exchange,提问作者user23020780
相关产品推荐
相关产品推荐

