Why can't one add/remove items from an ArrayAdapter?
Asked Answered
K

9

57

I am using an ArrayAdapter<CharSequence> to populate the items to list in a android.widget.Spinner. That works all fine.

But now I want to keep the list of items dynamic, i.e. I want to be able to add/remove items from the selection list at runtime. However, when I call adapter.add(item) or adapter.remove(item) I always get a UnsupportedOperationException, even though the Javadocs of the ArrayAdapter class describe these two methods as to be usable for exactly that intended purpose.

Is this a bug, really not implemented or what am I missing here?

Kurus answered 13/8, 2010 at 12:23 Comment(2)
I think a snippet could help.Monia
Duplicate of Unable to modify ArrayAdapter in ListViewNunez
T
121

You probably initialized the adapter with a plain Java array (e.g., String[]). Try using something that implements the java.util.List interface (e.g., ArrayList<String>).

Tongs answered 13/8, 2010 at 12:26 Comment(3)
I'm using an ArrayList<Form> and I getting UnsupportedOperationException. Form is a custom class.Datcha
Except when using Arrays.asList which returns a read-only ArrayList. See Zeratul's answer belowRaving
I initialed with Collections.<String>emptyList(), it died too. new ArrayList<String>) fixed the problem.Poise
T
22

I know it's late but just a quick explanation: it's because method Arrays.asList(T... array) returns custom inner class named ArrayList that is read-only. As already said, you need to provide full impl. e.g. java.util.ArrayList.

Turtle answered 26/8, 2011 at 12:4 Comment(0)
L
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();
}

The only thing that can throw an UnsupportedOperationException there is the line in the else-block. So the problem is that the list you're using doesn't support removing items. My guess is you're using an array. Try an ArrayList, for instance.

edit: So yeah, what Mark said...

Leslielesly answered 13/8, 2010 at 12:28 Comment(0)
O
13

I was having the same problem, my data was saved in resource String Array, so I was creating ArraAdapter with createFromResource.
The following code for creating ArrayAdapter from resource String Array solved the problem:

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)));
Od answered 14/6, 2012 at 20:20 Comment(0)
B
2

In your adapter Class - Delete an Item

remove(position);
notifyDataSetChanged();

Add an Item -

adapter.add (newItem);
adapter.notifyDataSetChanged ();
Barrens answered 10/9, 2012 at 2:32 Comment(1)
adapter.remove requires object, not position. And throws java.lang.UnsupportedOperationException.Ridiculous
B
1

Probably, you are using List in your ArrayAdapter class instead of ArrayList.

Try converting your array or list to ArrayList -

new ArrayList<ClassType>(Arrays.asList(array));
Bloomy answered 8/11, 2017 at 5:42 Comment(0)
J
0

You can try like this:

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

Example code how to implement:

String[] recentlyClient;

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

Juncaceous answered 19/11, 2020 at 0:15 Comment(0)
C
0

My nightmare was removing items from the ArrayAdapter<String>. I have been avoiding this method for almost 6 years because of this phenomenon :(

My Adapter was been:

 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;
    }
// ...
}

And now, it look like:

 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;
    }
// ...
}

Of course, after deleting the desired items, be sure to call:

adapter.notifyDataSetChanged();

Thanks for answers here.

Clearcut answered 6/6, 2021 at 16:36 Comment(0)
S
0

I think String [] has got the fixed size. So, we cannot add or remove element from it. So, When we want to remove element from the adapter which populated by string [] , the exception UnsupportedOperationException is thrown.

So, for this workaround we have to populate the adapter with java.util.List interface (e.g., ArrayList<String>).

Sabinesabino answered 13/1, 2023 at 19:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.