Why can't one add/remove items from an ArrayAdapter?
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 a开发者_运维技巧lways 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?
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>
).
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.
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...
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)));
In your adapter Class - Delete an Item
remove(position);
notifyDataSetChanged();
Add an Item -
adapter.add (newItem);
adapter.notifyDataSetChanged ();
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));
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)));
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.
精彩评论