如何删除通过布局XML的entries添加到Spinner中的项?
解决Spinner动态删除选项时抛出InvalidOperationException的问题
你遇到的这个问题很常见,原因是错误地使用了ViewGroup的视图操作方法来修改Spinner的选项。spinnerObject.removeViewAt(0)是用来移除Spinner本身的子View(比如Spinner内部的箭头控件等),而不是下拉列表里的选项——Spinner的选项是由Adapter负责管理的,不能直接通过视图操作来修改。
下面是正确的解决步骤:
核心思路
Spinner的选项数据完全由绑定的Adapter控制,要动态增删选项,必须先获取/创建可修改的数据源,通过修改数据源后通知Adapter更新,或者重新设置Adapter。
方法一:从一开始就用代码设置可修改的Adapter(推荐)
放弃XML中android:entries的配置,改用代码从strings.xml读取数组并转换为可修改的List,再绑定Adapter:
- 读取字符串数组并转为List:
// 获取strings.xml中的数组 String[] addressTypes = getResources().getStringArray(R.array.lst_addressTypes); // 转为ArrayList,方便后续修改 List<String> addressList = new ArrayList<>(Arrays.asList(addressTypes));
- 创建并绑定ArrayAdapter:
Spinner cboTipoDireccion = findViewById(R.id.cboTipoDireccion); // 创建Adapter,使用系统默认的Spinner布局 ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, addressList); // 设置下拉列表的布局 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // 绑定到Spinner cboTipoDireccion.setAdapter(adapter);
- 动态删除选项:
直接修改List,然后通知Adapter数据已变化:
// 删除第一个选项 addressList.remove(0); // 通知Adapter更新UI adapter.notifyDataSetChanged();
方法二:兼容已配置android:entries的情况
如果已经在XML里设置了android:entries,可以先获取原Adapter的数据,转为可修改的List后重新创建Adapter:
Spinner cboTipoDireccion = findViewById(R.id.cboTipoDireccion); // 获取原Adapter ArrayAdapter<String> oldAdapter = (ArrayAdapter<String>) cboTipoDireccion.getAdapter(); // 将原Adapter的数据转为可修改的List List<String> addressList = new ArrayList<>(); for (int i = 0; i < oldAdapter.getCount(); i++) { addressList.add(oldAdapter.getItem(i)); } // 删除指定位置的选项 addressList.remove(0); // 创建新的Adapter并绑定 ArrayAdapter<String> newAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, addressList); newAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); cboTipoDireccion.setAdapter(newAdapter);
关键提醒
- 永远不要通过
removeViewAt、addView这类ViewGroup方法修改Spinner的选项,这些方法操作的是Spinner自身的内部视图,和下拉选项无关。 - 只要数据源是可修改的(比如ArrayList),修改后调用
adapter.notifyDataSetChanged()就能自动更新Spinner的选项,不需要重新创建Adapter。
内容的提问来源于stack exchange,提问作者Exumer
相关产品推荐
相关产品推荐

