如何避免Spinner对应的ArrayList出现重复填充问题?
问题分析与解决方案
看起来你的Spinner重复填充问题,核心出在全局存储mBaseApp的错误使用和一些小的代码细节上,我来帮你拆解并修复:
核心问题定位
你在loadItemSubscription的循环里做了两个错误操作:
- 每次循环都调用
mBaseApp.setItemSubscription(modelItemSubscription)——这应该是把单个元素追加到全局列表里,而不是替换整个列表。 - 循环结束后,你用
mItemSubscriptionList = mBaseApp.getItemSubscription()覆盖了本地已经清空并重新填充的列表。
导致的结果就是:
- 首次加载时,全局列表是空的,循环添加4个元素,正常显示。
- 提交后再次加载,全局列表已经有之前的4个元素,你又把新的4个加进去,变成8个重复项,最后Spinner用这个重复的列表渲染。
另外还有个语法错误:quantity = quantity.replace(".00","";少了右引号,会导致编译失败,得先补上。
修正后的完整代码
private void loadItemSubscription() { ApiMapper mapper = new ApiMapper(); mapper.getBalance(new ApiMapper.VolleyCallback<JSONArray>() { @Override public void onSuccess(JSONArray balance) { if (balance != null) { Log.d(LOGTAG , balance.toString()); mItemSubscriptionList.clear(); // 清空本地列表,准备重新填充 for (int i = 0; i < balance.length(); i++) { Log.d(LOGTAG , "Popolo lo spinner "+i); try { JSONObject obj = balance.getJSONObject(i); String quantity = obj.getString("balance"); quantity = quantity.replace(".00", ""); // 修复语法错误 int id_item = obj.getInt("id_item"); String item = obj.getString("item"); item = item + ' '+'('+quantity+')'; Log.d(LOGTAG , quantity); Log.d(LOGTAG , item); ModelItemSubscription modelItemSubscription = new ModelItemSubscription(); modelItemSubscription.setMItemId(id_item); modelItemSubscription.setMItemName(item); modelItemSubscription.setMItemQuantity(quantity); mItemSubscriptionList.add(modelItemSubscription); // 移除循环内的mBaseApp.setItemSubscription,不要逐个添加到全局 } catch (JSONException e) { e.printStackTrace(); } } // 循环结束后,一次性把完整的本地列表设置到全局存储 // 注意:如果mBaseApp没有setItemSubscriptionList方法,需要你给它新增一个 mBaseApp.setItemSubscriptionList(mItemSubscriptionList); // 把对话框关闭移到这里,确保所有数据处理完成后再关闭 mLoadingDialog.dismiss(); } // 直接用本地已经填充好的列表渲染Spinner,不需要再从mBaseApp获取 if (mItemSubscriptionList != null && !mItemSubscriptionList.isEmpty()) { renderSpinnerItemSubscription(mItemSubscriptionList); } } }, mToken, mIdMemberCard, mIdCampaign); }
配套调整mBaseApp的代码
如果你的mBaseApp之前只有单个元素的设置方法,需要新增一个设置整个列表的方法:
// 在mBaseApp类中 private List<ModelItemSubscription> mItemSubscriptionList; // 新增设置整个列表的方法 public void setItemSubscriptionList(List<ModelItemSubscription> list) { this.mItemSubscriptionList = new ArrayList<>(list); // 深拷贝避免后续本地修改影响全局 } // 获取列表的方法保持不变 public List<ModelItemSubscription> getItemSubscription() { return mItemSubscriptionList; }
额外保障:Spinner适配器的更新逻辑
确保renderSpinnerItemSubscription方法每次都会清空旧数据再添加新数据,避免适配器残留旧条目:
private void renderSpinnerItemSubscription(List<ModelItemSubscription> list) { if (mSpinnerAdapter != null) { mSpinnerAdapter.clear(); mSpinnerAdapter.addAll(list); mSpinnerAdapter.notifyDataSetChanged(); } else { // 首次初始化适配器 mSpinnerAdapter = new YourCustomSpinnerAdapter(getContext(), list); mYourSpinner.setAdapter(mSpinnerAdapter); } }
关键修复总结
- 不要在循环内逐个更新全局列表,而是一次性设置完整的新列表。
- 修复语法错误,避免编译异常。
- 确保对话框在所有数据处理完成后再关闭。
- 确保Spinner适配器每次更新时清空旧数据。
内容的提问来源于stack exchange,提问作者sineverba
相关产品推荐
相关产品推荐

