0

I have a java.lang.UnsupportedOperationException at my Iterator .remove() but I believe this is considered safe and I think my code is actually "ok" so can someone help me?

    final List<String> liveList = Arrays.asList((String[]) button.getItems().toArray()); //create mutable List<String> from button.getItems() List<String>

    final PremSpinner dropdown = new PremSpinner(this); //spinner (EG: "dropdown") of all the options
    dropdown.setLayoutParams(col);
    final ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, liveList);        //      <---+
    dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);                                             //          |
    dropdown.setPadding(45, 15, 45, 15);                //                                                                                      |
    dropdown.setAdapter(dataAdapter);                   //the way you [populate] a `dropdown(spinner)` is via an `adapter` and a List<String>   |       


    final EditText partSearcher = new EditText(this);
    partSearcher.setLayoutParams(col);
    partSearcher.addTextChangedListener(new TextWatcher() {
        public void afterTextChanged(Editable s) {
            Log.w("typing",s.toString());
            Iterator<String> iter = liveList.iterator(); 
            while (iter.hasNext()) {
                if (!iter.next().contains(s)) {
                    iter.remove();  //<--the UnsupportedOperationException is here
                }
            }
            dataAdapter.notifyDataSetChanged();
        }
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
        public void onTextChanged(CharSequence s, int start, int before, int count) {}
    });

then I add them to the table

    tr = new TableRow(this);        
    tr.setLayoutParams(lp);
    tr.addView(partSearcher);
    table.addView(tr, new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

    tr = new TableRow(this);    
    tr.setLayoutParams(lp);
    tr.addView(dropdown);       
    table.addView(tr, new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); //this makes it fat enough

the code is designed to be portable for people who want a text search in their spinner, there is a lot of interest in dynamic spinner but no solid workable code examples, so I was hoping to make this one a blog article, but I can't figure it out!

user26676
  • 280
  • 3
  • 21

2 Answers2

0

The iterator in this case is based on List which does not support remove();

You would need to pass in the actual object or the index of the object you want to remove.

nPn
  • 16,254
  • 9
  • 35
  • 58
  • normally I'd agree bit then I read this http://stackoverflow.com/questions/223918/efficient-equivalent-for-removing-elements-while-iterating-the-collection – user26676 Sep 03 '13 at 16:27
  • http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Iterator.html#remove() says that exception would come from the iterator not supporting remove() ... and yes the issue I had was with concurrent modification not this – nPn Sep 03 '13 at 16:46
  • it looks like List<> does not support remove(); .. it want s an int or object. – nPn Sep 03 '13 at 16:51
  • the issue is that `liveList` is final. – user26676 Sep 04 '13 at 09:00
  • -- EDIT -- actually no this was wrong, the issue is that `ArrayAdapter.createFromResource()` uses `Arrays.asList()` as described here http://stackoverflow.com/a/5999761/2260952 – user26676 Sep 04 '13 at 10:24
0

ok for prosperity I am going to fully answer this question. The code was sound it was a tiny issue regarding the immutable nature of the Arrays.asList created secretly as part of the hidden createFromResource() constructor call.

This is a searchable / text filtered spinner (aka: dropdown or selectbox or combobox) for Android written in Java that works. It is programmatically flexible (does not rely on XML - so it's perfect for dialog, which is where I use it as a Just-In-Time popup)

//assuming that getItems() is a List<String> of your Spinner contents
final List<String> liveList = Arrays.asList((String[]) getItems().toArray()); //create mutable List<String> from getItems() List<String>

final Spinner dropdown = new Spinner(this); //spinner (EG: "dropdown") of all the options
dropdown.setLayoutParams(col);
final ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, new ArrayList<String>());     //      <---+
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);                                                         //          |
dropdown.setPadding(45, 15, 45, 15);                //                                                                                                  |
dropdown.setAdapter(dataAdapter);                   //the way you [populate] a `dropdown(spinner)` is no longer via a List<String>                      |       

Iterator<String> iter = liveList.iterator(); 
while (iter.hasNext()) {    
    dataAdapter.add(iter.next());
}   //instead of using the constructor we [populate] them "dynamically" directly into the ArrayAdapter


final EditText partSearcher = new EditText(this);
partSearcher.setLayoutParams(col);
partSearcher.addTextChangedListener(new TextWatcher() {
        public void afterTextChanged(Editable s) {
            Log.w("typing",s.toString());
            List<String> keepList = new ArrayList<String>();
            Iterator<String> iter = liveList.iterator(); 
            while (iter.hasNext()) {
                String menow = iter.next();
                if (menow.toLowerCase().contains(s.toString().toLowerCase())) {
                    keepList.add(menow);
                }
            }
            dataAdapter.clear();
            dataAdapter.addAll(keepList);
            dataAdapter.notifyDataSetChanged();
        }
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
        public void onTextChanged(CharSequence s, int start, int before, int count) {}
});

you can then add these dynamically to a table as it shows in the 2nd code block of the original question

please note there are some setLayoutParams calls that are not explained - these are merely there as good practise for my own needs and can be left out

Community
  • 1
  • 1
user26676
  • 280
  • 3
  • 21