【发布时间】:2015-02-17 18:18:43
【问题描述】:
美好的一天,我有以下代码,但我不明白为什么我偶尔会收到上述错误消息。有时我明白了.. 有时我没有,但我想摆脱它.. 我已经尝试了一切(有些已注释掉)和一些答案,但仍然遇到了麻烦。你们能不能请看一下它并说出哪里出了问题,因为我似乎没有注意到它。
public class SearchAutoCompleteAdapter extends BaseAdapter implements Filterable {
private ArrayList<BaseAutocompleteItems> resultList;
private LayoutInflater layoutInflater;
private Context context;
private int layout;
SearchAutoCompleteAPI searchautocomplete = new SearchAutoCompleteAPI(); //does API operation
public SearchAutoCompleteAdapter(Context context, int resource) {
super();
this.context = context;
this.layout = resource;
this.resultList = new ArrayList<BaseAutocompleteItems>();
}
@Override
public int getCount() {
return resultList.size();
}
@Override
public Object getItem(int index) {
return resultList.get(index);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(layout, null);
}
TextView name = (TextView) convertView.findViewById(R.id.suggestion_text_id);
TextView category = (TextView) convertView.findViewById(R.id.suggestion_category_text_id);
name.setText(resultList.get(position).getName());
category.setText(resultList.get(position).getCategoryName());
return convertView;
}
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
List<BaseAutocompleteItems> tempfilteredProducts;
//synchronized (filterResults) {
if (constraint != null || constraint.length() == 0) {
Log.d(SearchogHomeActivity.TAG, "characters in constraints is not null");
tempfilteredProducts = searchautocomplete.autocomplete(constraint.toString());
} else {
tempfilteredProducts = new ArrayList<BaseAutocompleteItems>();
}
filterResults.values = tempfilteredProducts;
filterResults.count = tempfilteredProducts.size();
return filterResults;
//}
}
@Override
protected void publishResults (CharSequence constraint, final FilterResults results){
//synchronized (results) {
resultList = (ArrayList<BaseAutocompleteItems>) results.values;
if (results != null && results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
// }
};
return filter;
}
}
这是我在活动中使用它的地方:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category);
textEdit = (AutoCompleteTextView)findViewById(R.id.search_autocomplete_id);
adapter = new SearchAutoCompleteAdapter(this, R.layout.autocomplete_list);
textEdit.setText("");
//textEdit.setThreshold(0);
textEdit.setOnItemClickListener(this);
textEdit.setAdapter(adapter);
这是我要求的日志:
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. [in ListView(-1, class android.widget.ListPopupWindow$DropDownListView) with Adapter(class com.Example.searchAdapter.adapter.SearchAutoCompleteAdapter)]
at android.widget.ListView.layoutChildren(ListView.java:1562)
at android.widget.AbsListView.onLayout(AbsListView.java:2148)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2072)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1829)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5779)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
API 调用:
public ArrayList<BaseAutocompleteItems> autocomplete(String s){
//final ArrayList<BaseAutocompleteItems> myresultList = new ArrayList<BaseAutocompleteItems>();
//myresultList.clear();
String input = BASE_AUTOCOMPLETE_URL + s;
Log.d(SearchActivity.TAG, "AutoComplete string is " + input );
SearchRestClient.get(input, null, new JsonHttpResponseHandler(){
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
super.onSuccess(statusCode, headers, response);
}
@Override
public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
super.onSuccess(statusCode, headers, response);
ObjectMapper objectmapper = new ObjectMapper();
objectmapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
//1
//List<BaseAutocompleteItems> autocompleteItems = objectmapper.readValue(String.valueOf(response), objectmapper.getTypeFactory().constructCollectionType(ArrayList.class, BaseAutocompleteItems.class));
myresultList = objectmapper.readValue(String.valueOf(response), objectmapper.getTypeFactory().constructCollectionType(ArrayList.class, BaseAutocompleteItems.class));
//2
/* myresultList.clear();
for(BaseAutocompleteItems items: autocompleteItems){
myresultList.add(items);
}*/
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
super.onFailure(statusCode, headers, throwable, errorResponse);
}
@Override
public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONArray errorResponse) {
super.onFailure(statusCode, headers, throwable, errorResponse);
}
});
Log.d(SearchActivity.TAG, "size in adapter is " + myresultList.size());
return myresultList;
}
【问题讨论】:
-
为什么要使用 TextWatcher?
-
@Luksprog 很抱歉回复很晚,我昨天下班时发布了这个。在调用 APi 之前,我最初使用它来获取字符数,但后来我停止了。我现在将从代码中删除它,但仍然是同样的问题。我已经包括了日志。谢谢
-
@Josef 很抱歉回复晚了,发布此消息后无法访问我的电脑。我已经包含了我的日志文件。
-
除非您在 SearchAutoCompleteAPI 类中做一些可疑的事情(它是适配器中的内部类?如果是,则发布其代码)您当前的代码不应该真正抛出该异常。
-
@Luksprog 嗨..我已经发布了 API 调用,但我想我找到了问题的原因。我正在使用 for 循环执行以下操作(用数字 1 和 2 注释掉的行)来填充 myresultList 而不是直接执行。我猜这可能是可疑的东西吗?现在正在测试很多以确保并会让您知道。
标签: android