应用程序崩溃与ANR :: IllegalStateException:适配器的内容已更改但ListView未收到通知。

时间:2015-12-22 07:34:18

标签: android listview android-listview android-adapter android-filter

我用适配器创建了一个listview。使用过滤器实现搜索。它工作正常。但有时应用程序崩溃时出现以下错误:

java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes.

在ListView活动中,当用户在文本框中输入内容时,我使用以下代码调用搜索。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.list_view_layout);
    mAdapter = new ListViewAdapter(this);
    ...

    mSearchEditText = (EditText) findViewById(R.id.search_text);
    mSearchEditText.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            Log.v("ListViewActivity", "SearchTextBox: onTextChanged <" + s + ">");
            mAdapter.getFilter().filter(s);
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

在ListViewAdapter中,我使用过滤器在列表视图中实现搜索:

public class ListViewAdapter extends BaseAdapter implements Filterable{
private ArrayList<ListItem> mOriginalList;
private ArrayList<ListItem> mDisplayedList;

...

@Override
public Filter getFilter() {
    Filter filter = new Filter() {

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            Log.v("ListViewAdapter", "Filter: publishResults constraint<" + constraint + ">");
            notifyDataSetChanged();
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            Log.v("ListViewAdapter", "Filter: performFiltering constraint<" + constraint + ">");
            FilterResults filterResults = new FilterResults();

            mDisplayedList.clear();

            if (constraint == null || constraint.length() == 0) {
                mDisplayedList.addAll(mOriginalList);
                filterResults.count = mDisplayedList.size();
                filterResults.values = mDisplayedList;
            } else {
                String searchText = constraint.toString().toLowerCase();
                for (ListItem listItem : mOriginalList) {
                    if (listItem.getKeyName().toLowerCase().contains(searchText) 
                            || listItem.getKeyValue().toLowerCase().contains(searchText)) {
                        mDisplayedList.add(listItem);
                    }
                }

                filterResults.count = mDisplayedList.size();
                filterResults.values = mDisplayedList;
            }

            Log.v("ListViewAdapter", "Filter: performFiltering filterResults.count<" + filterResults.count + ">");
            return filterResults;
        }
    };

    return filter;
}

4 个答案:

答案 0 :(得分:0)

使用:mAdapter.notifyDataSetChanged();

答案 1 :(得分:0)

onTextChanged中,拨打mAdapter.notifyDataSetChanged()

答案 2 :(得分:0)

 java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes.

出现此问题是因为您在主线程上设置了适配器。而不需要在UI thread中设置适配器。与使用AsyncTask方法中的onPostExecute()设置适配器或使用onHandledMessage() Handler方法Thread方法一样。

答案 3 :(得分:0)

问题已解决。我移动代码将mDisplayedList更新为publishResults(),而不是在performFiltering()for循环中继续更新。更新mDisplayedList并一起调用notifyDataSetChanged()。我认为这是最好的解决方案。

@Override
public Filter getFilter() {
    Filter filter = new Filter() {

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            Log.v("ListViewAdapter", "Filter: publishResults constraint<" + constraint + ">");

            if (results.count == 0) {
                mDisplayedList.clear();
                notifyDataSetInvalidated();
            } else {
                mDisplayedList.clear();
                mDisplayedList.addAll((ArrayList<ListItem>) results.values);
                notifyDataSetChanged();
            }
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            Log.v("ListViewAdapter", "Filter: performFiltering constraint<" + constraint + ">");
            FilterResults filterResults = new FilterResults();
            ArrayList<ListItem> filteredList = new ArrayList<ListItem>();

            if (constraint == null || constraint.length() == 0) {
                filteredList.addAll(mOriginalList);
            } else {
                String searchText = constraint.toString().toLowerCase();
                for (ListItem listItem : mOriginalList) {
                    if (listItem.getKeyName().toLowerCase().contains(searchText) 
                            || listItem.getKeyValue().toLowerCase().contains(searchText)) {
                        filteredList.add(listItem);
                    }
                }
            }

            filterResults.count = filteredList.size();
            filterResults.values = filteredList;
            Log.v("ListViewAdapter", "Filter: performFiltering filterResults.count<" + filterResults.count + ">");
            return filterResults;
        }
    };

    return filter;
}