101

I'm trying to make a list containing names. This list should be modifiable (add, delete, sort, etc). However, whenever I tried to change the items in the ArrayAdapter, the program crashed, with java.lang.UnsupportedOperationException error. Here is my code:

ListView panel = (ListView) findViewById(R.id.panel);
String[] array = {"a","b","c","d","e","f","g"};
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, array);
adapter.setNotifyOnChange(true);
panel.setAdapter(adapter);

Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
      adapter.insert("h", 7);
   }
});

I tried insert, remove and clear methods, and none of them worked. Would someone tell me what I did wrong?

blahdiblah
  • 33,069
  • 21
  • 98
  • 152
Ryan
  • 1,013
  • 2
  • 7
  • 4

1 Answers1

301

I tried it out myself and found it didn't work, so I checked out the source code of ArrayAdapter and found out the problem: The ArrayAdapter, on being initialized by an array, converts the array into an AbstractList (List<String>) which cannot be modified.

Solution Use an ArrayList<String> instead using an array while initializing the ArrayAdapter.

String[] array = {"a","b","c","d","e","f","g"}; 
ArrayList<String> lst = new ArrayList<String>(Arrays.asList(array));
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
android.R.layout.simple_list_item_1, lst);
starball
  • 20,030
  • 7
  • 43
  • 238
st0le
  • 33,375
  • 8
  • 89
  • 89
  • 9
    Thank you so much! You saved me hours of frustration. Would you mind explain to me why String[] didn't work? – Ryan Jul 08 '10 at 04:20
  • @Ryan you can't insert into an array, you can into a list, unless the list implementation doesn't allow it. If your backing data is not going to change, ArrayAdapter allows you to use a more memory efficient technique. – Stephen Denne Jul 08 '10 at 04:27
  • @st0le what difference it makes if I pass "new ArrayList(Arrays.asList(array))" or just "Arrays.asList(array)"? The first works and the second doesn't. – golosovsky Dec 12 '15 at 09:14
  • 1
    @golosovsky, In the first one, you create a Mutable List, the second way creates a Immutable List. (cannot be modified once created) – st0le Jan 09 '16 at 00:11
  • An insert in an array is quite possible, Arrays.copyOf and System.arraycopy will do the trick. I think a developer of the API was simply lazy – Singagirl Sep 09 '16 at 02:42
  • How will you update the reference of the original array that was passed to the adapter with the copy? It's a clean design decision, your comments are very callous. – st0le Sep 09 '16 at 19:00
  • 4
    It's 2016 and still this ridiculous exception thrown at this specific scenario. – Eido95 Dec 11 '16 at 13:14
  • Thanks so much! Can't believe they'll never document this out, or stop allowing immutables if they plan to provide something like notifyDatasetChanged – Aman Alam Sep 28 '17 at 16:01