为什么无法向ArrayAdapter中添加/删除项目?

57

我正在使用一个 ArrayAdapter<CharSequence> 来填充在 android.widget.Spinner 中显示的选项。这一切都很好。

但现在我想让此列表动态变化,也就是说,我希望能够在运行时添加/删除选择列表中的项目。然而,当我调用 adapter.add(item)adapter.remove(item) 时,总是会出现 UnsupportedOperationException,尽管 ArrayAdapter 类的 Javadocs 描述了这两种方法可用于实现这一预期目的。

这是一个错误吗,还是真的没有实现,或者我少了什么重要信息?


1
我认为代码片段可能会有所帮助。 - Federico klez Culloca
重复的问题:无法修改ListView中的ArrayAdapter - blahdiblah
9个回答

121

你可能使用了普通的Java数组(例如:String[])来初始化Adapter。尝试使用实现了java.util.List接口的内容(例如:ArrayList<String>)。


4
我正在使用一个 ArrayList<Form> 并且遇到了 UnsupportedOperationException 异常。其中 Form 是一个自定义类。 - VansFannel
2
除非使用返回只读 ArrayList 的 Arrays.asList。请参见下面 Zeratul 的答案。 - andrei
我最初使用了 Collections.<String>emptyList(),但它也出现了问题。new ArrayList<String> 解决了这个问题。 - Miao1007

22

我知道现在已经很晚了,但是让我简单解释一下:这是因为方法Arrays.asList(T... array)返回的自定义内部类名为ArrayList且是只读的。正如前面所说,你需要提供完整的实现,例如java.util.ArrayList。


16

Here's the source code of ArrayAdapter#remove:

public void remove(T object) {
    if (mOriginalValues != null) {
        synchronized (mLock) {
            mOriginalValues.remove(object);
        }
    } else {
        mObjects.remove(object);
    }
    if (mNotifyOnChange) notifyDataSetChanged();
}

在else块中唯一可能抛出UnsupportedOperationException的是那行代码。所以问题在于你使用的列表不支持删除项目。我猜你正在使用一个数组。尝试使用ArrayList。

编辑:所以,是的,就像Mark说的那样...


13

我曾遇到相同的问题,我的数据保存在资源字符串数组中,因此我使用createFromResource创建了ArraAdapter。
以下代码将资源字符串数组用于创建ArrayAdapter解决了问题:

Resources res = getResources();
String[] cities = res.getStringArray(R.array.cities_array);
ArrayAdapter<CharSequence> adapter = new ArrayAdapter(
     this,
     android.R.layout.simple_spinner_item,
     new ArrayList(Arrays.asList(cities)));

2

在您的适配器类中 - 删除一个项

remove(position);
notifyDataSetChanged();

添加项目 -
adapter.add (newItem);
adapter.notifyDataSetChanged ();

adapter.remove需要对象而非位置,并会抛出java.lang.UnsupportedOperationException异常。 - Spectorsky

1
也许,在您的ArrayAdapter类中使用了List而不是ArrayList。
尝试将您的数组或列表转换为ArrayList -
new ArrayList<ClassType>(Arrays.asList(array));

0

我的噩梦是从 ArrayAdapter<String> 中移除项目。由于这种现象,我已经避免使用这种方法将近6年了 :(

我的适配器是:

 private class MyAdapter extends ArrayAdapter<String> {
    private final Context context;
    private final Bitmap[] slike;
    private final String[] nazivi;
    private final String[] grad_freq;
    private final boolean[] omiljeni;

    MyAdapter (Context c, Bitmap[] slike, String[] nazivi, String[] grad_freq, boolean[] omiljeni) {
        super(c, R.layout.row, R.id.textView1, nazivi);
        this.context = c;
        this.slike = slike;
        this.nazivi = nazivi;
        this.grad_freq= grad_freq;
        this.omiljeni = omiljeni;
    }
// ...
}

现在,它看起来像:

 private class MyAdapter extends ArrayAdapter<String> {
    private final Context context;
    private final ArrayList<Bitmap> slike;
    private final ArrayList<String> nazivi;
    private final ArrayList<String> grad_freq;
    private final ArrayList<Boolean> omiljeni;

    MyAdapter (Context c, ArrayList<Bitmap> slike, ArrayList<String> nazivi, ArrayList<String> grad_freq, ArrayList<Boolean> omiljeni) {
        super(c, R.layout.row, R.id.textView1, nazivi);
        this.context = c;
        this.slike = slike;
        this.nazivi = nazivi;
        this.grad_freq= grad_freq;
        this.omiljeni = omiljeni;
    }
// ...
}

当然,在删除所需项目后,请确保调用以下代码:
adapter.notifyDataSetChanged();

感谢这里的回答。


0

我认为 String [] 的大小是固定的。因此,我们无法添加或删除其中的元素。所以,当我们想要从由 string [] 填充的适配器中移除元素时,会抛出异常 UnsupportedOperationException

因此,为了解决这个问题,我们必须使用 java.util.List 接口(例如,ArrayList<String>)来填充适配器。


0

你可以这样尝试:

new ArrayList<>(Arrays.asList(recentlyClient))

如何实现的示例代码:

String[] recentlyClient;

ArrayAdapter<String> recenAdapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,new ArrayList<>(Arrays.asList(recentlyClient)));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接