Android, ListView IllegalStateException: “The content of the adapter has changed but ListView did not receive a notification”

后端 未结 25 2357
执念已碎
执念已碎 2020-11-22 16:59

What I want to do: run a background thread which calculates ListView contents and update ListView partially, while results are calculated.

W

25条回答
  •  忘了有多久
    2020-11-22 17:44

    My issue was related to the use of a Filter together with the ListView.

    When setting or updating the underlying data model of the ListView, I was doing something like this:

    public void updateUnderlyingContacts(List newContacts, String filter)
    {
        this.allContacts = newContacts;
        this.filteredContacts = newContacts;
        getFilter().filter(filter);
    }
    

    Calling filter() in the last line will (and must) cause notifyDataSetChanged() to be called in the Filter's publishResults() method. This may work okay sometimes, specially in my fast Nexus 5. But in reality, it's hiding a bug that you will notice with slower devices or in resource intensive conditions.

    The problem is that the filtering is done asynchronously, and thus between the end of the filter() statement and the call to publishResults(), both in the UI thread, some other UI thread code may execute and change the content of the adapter.

    The actual fix is easy, just call notifyDataSetChanged() also before requesting the filtering to be performed:

    public void updateUnderlyingContacts(List newContacts, String filter)
    {
        this.allContacts = newContacts;
        this.filteredContacts = newContacts;
        notifyDataSetChanged(); // Fix
        getFilter().filter(filter);
    }
    

提交回复
热议问题