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

如何避免Spinner对应的ArrayList出现重复填充问题?

问题分析与解决方案

看起来你的Spinner重复填充问题,核心出在全局存储mBaseApp的错误使用和一些小的代码细节上,我来帮你拆解并修复:

核心问题定位

你在loadItemSubscription的循环里做了两个错误操作:

  1. 每次循环都调用mBaseApp.setItemSubscription(modelItemSubscription)——这应该是把单个元素追加到全局列表里,而不是替换整个列表。
  2. 循环结束后,你用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);
    }
}

关键修复总结

  1. 不要在循环内逐个更新全局列表,而是一次性设置完整的新列表。
  2. 修复语法错误,避免编译异常。
  3. 确保对话框在所有数据处理完成后再关闭。
  4. 确保Spinner适配器每次更新时清空旧数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:58:06