IllegalStateException异常:适配器的内容发生了变化,但ListView控件没有收到通知 [英] IllegalStateException: The content of the adapter has changed but ListView did not receive a notification
问题描述
我使用的是自定义ArrayAdapter设置上AutocompleteTextView适配器(AddressAdapter扩展ArrayAdapter)。
I'm using a custom ArrayAdapter to set the adapter on an AutocompleteTextView (AddressAdapter extends ArrayAdapter).
public class AutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {
private ArrayList<String> mData;
ArrayList<String> listTempPrefix = new ArrayList<String>();
ArrayList<String> listTemp = new ArrayList<String>();
String valueText;
String[] words;
String ulcase;
public AutoCompleteAdapter(Context context, int textViewResourceId, ArrayList<String> bS) {
super(context, textViewResourceId);
mData = bS;//new ArrayList<String>();
}
@Override
public int getCount()
{
synchronized (listTempPrefix)
{
return listTempPrefix.size();
}
}
@Override
public String getItem(int index)
{
synchronized (listTempPrefix)
{
try {
//Log.e("Error", listTempPrefix.get(index));
return listTempPrefix.get(index);
} catch(IndexOutOfBoundsException e) {
Log.e("Error", "IndexOutOfBoundsException");
return "";
}
}
}
@Override
public Filter getFilter()
{
Filter myFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint)
{
FilterResults filterResults = new FilterResults();
synchronized (filterResults)
{
listTempPrefix.clear();
listTemp.clear();
//Log.e("1", "1");
try {
if(constraint != null) {
// A class that queries a web API, parses the data and returns an ArrayList<Style>
//StyleFetcher fetcher = new StyleFetcher();
//try {
//mData = fetcher.retrieveResults(constraint.toString());
//}
//catch(Exception e) {}
// Now assign the values and count to the FilterResults object
for(String value: mData) {
valueText = value.toLowerCase();
//System.out.println("constraintH - " + constraint);
constraint.toString().toLowerCase();
ulcase = constraint.toString().toLowerCase();
//System.out.println("ulcase - " + ulcase);
if (valueText.startsWith(ulcase)) {
listTempPrefix.add(value);
} else {
words = valueText.split(" ");
//final int wordCount = words.length;
// Start at index 0, in case valueText starts with space(s)
for (int k = 0; k < words.length; k++) {
if (words[k].startsWith(ulcase)) {
listTemp.add(value);
break;
}
}
}
///listTemp.add(mData.get(i));
//filterResults.count = mData.size();
// System.out.println("mData" + i + mData.get(i));
}
//Log.e("2", "2");
// System.out.println("size " + listTemp.size() + " value" + listTemp);
listTempPrefix.addAll(listTemp);
filterResults.values = listTempPrefix;
filterResults.count = listTempPrefix.size();
//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;
}
}
@Override
protected void publishResults(CharSequence contraint, FilterResults filterResults)
{
synchronized (filterResults)
{
if(filterResults != null && filterResults.count > 0) {
notifyDataSetChanged();
//Log.e("notifyDataSetChanged", "notifyDataSetChanged");
}
else {
notifyDataSetInvalidated();
//Log.e("notifyDataSetInvalidated", "notifyDataSetInvalidated");
}
}
}
};
return myFilter;
}
}
我该怎么有时:请注意,它真的发生了罕见。但我想摆脱这种错误完全。下面是部分堆栈跟踪:
What I got sometimes: please notice, it happens really rarely. But I'd like to get rid of this bug completely. Here is partial stacktrace:
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. [in ListView(-1, class android.widget.AutoCompleteTextView$DropDownListView) with Adapter(class com.example.test.AutoCompleteAdapter)].
该问题可能从时,键盘的快速输入,法notifyDataSetChanged()issn't调用。但是我'不知道。
The problem maybe that the fast input from keybord, method notifyDataSetChanged () issn't call. But i'am not sure.
推荐答案
更改publishResults到
Change publishResults to
@Override
protected void publishResults(final CharSequence contraint, final FilterResults filterResults) {
listTempPrefix = (List) results.values;
if(filterResults != null && filterResults.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
这样的图形用户界面线程更新,而不是performFiltering结果它运行在后台线程。
This way the GUI thread updates the results instead of performFiltering which runs in a background thread.
卸下performFiltering listTemp preFIX参考,使用局部变量有存储结果,并通过FilterResults返回它们
Remove listTempPrefix references from performFiltering and use a local variable there to store the results and return them through FilterResults
这篇关于IllegalStateException异常:适配器的内容发生了变化,但ListView控件没有收到通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!