Android Studio Java单Adapter使用两个ArrayList出现索引越界如何解决
问题原因
- 核心报错来源于API返回的
cuzdanList(即Adapter中的mData)和数据库返回的cuzdanModels列表不同步:- API请求
call.enqueue是异步执行的,在API结果返回之前,mData是空列表,但Adapter的getItemCount返回的是数据库列表的长度,只要数据库有数据,RecyclerView就会触发onBindViewHolder,此时调用mData.get(position)就会直接抛出下标越界异常。 - 即使API请求完成,你默认两个列表下标位置对应的是同一个币种的逻辑本身就有问题:API返回的是全量500个币种的列表,顺序和你数据库中存储的用户持有币种的顺序不可能完全一致,就算长度相同也会出现数据不匹配,长度不同依然会触发越界。
- API请求
修复方案
1. 调整Adapter取值逻辑(核心修复)
不要按下标取API数据,改为用币种标识匹配对应的数据,同时增加空判断避免越界:
@Override public void onBindViewHolder(@NonNull CardTasarimTutucu holder, int position) { CuzdanModel cuzdan = cuzdanList.get(position); holder.textViewCoinAdi.setText(cuzdan.getCoin_adi()); holder.textViewAlisFiyatiAdapter.setText(String.format("%.3f",cuzdan.getCoin_alis_fiyati())); holder.textViewCoinAdediAdapter.setText(String.format("%.3f",cuzdan.getCoin_alis_adeti())); // 匹配对应币种的API数据 Datum matchDatum = null; if (mData != null && !mData.isEmpty()) { for (Datum datum : mData) { // 这里的匹配字段可根据你的实际字段调整,比如匹配币种名/币种代码 if (datum.getName().equals(cuzdan.getCoin_adi()) || datum.getSymbol().equals(cuzdan.getCoin_adi())) { matchDatum = datum; break; } } } if (matchDatum != null) { holder.textViewCoinDegeriAdapter.setText(String.valueOf(matchDatum.getQuote().getUSD().getPrice())); } else { // 数据未加载或未匹配到时显示占位值 holder.textViewCoinDegeriAdapter.setText("--"); } }
2. 可选优化
调整Fragment初始化顺序,先完成列表初始化再发起API请求,逻辑更通顺:
@Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.varliklarim_fragment_layout, container, false); vt = new VeriTabani(getActivity()); cuzdan_rc=rootView.findViewById(R.id.cuzdan_recycler_view); api = ApiClient.getClient().create(CoinMarketApi.class); // 先初始化列表 RecyclerBagla(rootView); // 再发起API请求 CoinList(); return rootView; }
内容的提问来源于stack exchange,提问作者Doğukan Çiftçi
相关产品推荐
相关产品推荐

