Skip to content Skip to sidebar Skip to footer

Illegalstateexception: The Content Of The Adapter Has Changed But Listview Did Not Receive A Notification

I'm using a custom ArrayAdapter to set the adapter on an AutocompleteTextView (AddressAdapter extends ArrayAdapter). public class AutoCompleteAdapter extends ArrayAdapter

Solution 1:

Change publishResults to

@OverrideprotectedvoidpublishResults(final CharSequence contraint, final FilterResults filterResults) { 
    listTempPrefix = (List) results.values;
    if(filterResults != null && filterResults.count > 0) {
        notifyDataSetChanged();
    } else {
        notifyDataSetInvalidated();
    }
}

This way the GUI thread updates the results instead of performFiltering which runs in a background thread.

Remove listTempPrefix references from performFiltering and use a local variable there to store the results and return them through FilterResults

Solution 2:

You're changing the listTempPrefix array on performFiltering (using clear and addAll), so you would need to call notifyDataSetChanged to avoid this exception.

But performFiltering is not called on the ui thread, so calling notifyDataSetChanged would also raise an exception.

The best way to solve this problem is changing the listTempPrefix array inside publishResults, and then call notifyDataSetChanged.

Remove the changes made to listTempPrefix from the performFiltering method (you might need to create a temp array depending on your filter logic).

On publishResults, update your listTempPrefix array with the values contained on filterResults, and call notifyDataSetChanged.

Here is an exemple based on your code:

@Overridepublic Filter getFilter()
{
    FiltermyFilter=newFilter() {
        @Overrideprotected FilterResults performFiltering(CharSequence constraint)
        {

            FilterResultsfilterResults=newFilterResults();
            synchronized (filterResults)
            {
                //listTempPrefix.clear(); // Don't change listTempPrefix here
                 ...
                        ulcase = constraint.toString().toLowerCase();
                        //System.out.println("ulcase - " + ulcase);if (valueText.startsWith(ulcase)) {
                            //listTempPrefix.add(value); // Don't change listTempPrefix// To keep your logic you might need an aux array // for this part
                        } else {
                            ...
                        }

                    //listTempPrefix.addAll(listTemp); // Don't change it

                    filterResults.values = listTempPrefix; // No problem here

                    filterResults.count = listTempPrefix.size(); // No problem here//System.out.println("size " + filterResults.count + " value" + filterResults.values);//System.out.println("constraint" + constraint);

                }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    }
                return filterResults;
            }
        }

        @OverrideprotectedvoidpublishResults(CharSequence contraint, FilterResults filterResults) 
        {
            // At this point, make the changes you need to listTempPrefix// using filterResults.valuessynchronized (filterResults)
            {
                if(filterResults != null && filterResults.count > 0) {
                notifyDataSetChanged();
                //Log.e("notifyDataSetChanged", "notifyDataSetChanged");
                }
                else {
                    notifyDataSetInvalidated();
                    //Log.e("notifyDataSetInvalidated", "notifyDataSetInvalidated");
                }
            }
        }
    };
    return myFilter;
}

Solution 3:

You must call the notifyDataSetChanged() method as soon as the dataset (ArrayList, Array, Cursor, etc.,) backing your Adapter changes. Or else you will end up with this Exception.

Post a Comment for "Illegalstateexception: The Content Of The Adapter Has Changed But Listview Did Not Receive A Notification"