AutocompleteTextView IllegalStateException:适配器的内容已更改,但ListView未收到通知

时间:2015-02-17 18:18:43

标签: android

美好的一天,我有以下代码,我无法理解为什么我偶尔会收到上述错误消息。有时候我会得到它...有时候我不会,但我想摆脱它..我已经尝试了所有的东西(一些评论)和一些答案,但仍然有麻烦。请你好好看看它,并说出错的地方,因为我似乎无法注意到它。

 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;

    }

2 个答案:

答案 0 :(得分:1)

这是getFilter方法:工作正常

@Override
public Filter getFilter() {
    Filter filter = new Filter() {
        @Override
        protected FilterResults performFiltering(final CharSequence constraint) {
            final FilterResults filterResults = new FilterResults();


                    resultList = autocomplete(constraint.toString());

                    // Assign the data to the FilterResults
                    filterResults.values = resultList;
                    filterResults.count = resultList.size();






            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint, final FilterResults results) {
            try {
               activity.runOnUiThread(new Runnable() {
                   @Override
                   public void run() {
                       if (results != null && results.count > 0) {

                          // resultList=(ArrayList<String>)results.values;
                           notifyDataSetChanged();
                       } else {
                           notifyDataSetInvalidated();
                       }
                   }
               });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };
    return filter;
}


    public static ArrayList<String> autocomplete(String input) {
    ArrayList<String> resultList = null;


    HttpURLConnection conn = null;
    StringBuilder jsonResults = new StringBuilder();
    try {
        StringBuilder sb = new StringBuilder(Constant.PLACES_API_BASE + Constant.TYPE_AUTOCOMPLETE + Constant.OUT_JSON);
        sb.append("?key=AIzaSyAlU5QFZWbgInmPlV-LWFlXiRS7pZ8wD8o");
        //sb.append("&components=country:au");
        //sb.append("&location=" + String.valueOf(LocationHelperService.dblLatitude) + "," + String.valueOf(LocationHelperService.dblLongitude));
        sb.append("&input=" + URLEncoder.encode(input, "utf8"));
        sb.append("&radius=" + String.valueOf(50));

        URL url = new URL(sb.toString());

        System.out.println("URL: " + url);
        conn = (HttpURLConnection) url.openConnection();
        InputStreamReader in = new InputStreamReader(conn.getInputStream());

        // Load the results into a StringBuilder
        int read;
        char[] buff = new char[1024];
        while ((read = in.read(buff)) != -1) {
            jsonResults.append(buff, 0, read);
        }
    } catch (MalformedURLException e) {
        Log.e(LOG_TAG, "Error processing", e);
        return resultList;
    } catch (IOException e) {
        Log.e(LOG_TAG, "Error connecting to Places API", e);
        return resultList;
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }

    try {
        // Create a JSON object hierarchy from the results
        JSONObject jsonObj = new JSONObject(jsonResults.toString());
        JSONArray predsJsonArray = jsonObj.getJSONArray("predictions");

        // Extract the Place descriptions from the results
        resultList = new ArrayList<String>(predsJsonArray.length());
        mainTextList=new ArrayList<String>(predsJsonArray.length());
        secondoryTextList=new ArrayList<String>(predsJsonArray.length());


        for (int i = 0; i < predsJsonArray.length(); i++) {
            System.out.println(predsJsonArray.getJSONObject(i).getString("description"));
            System.out.println("============================================================");
            resultList.add(predsJsonArray.getJSONObject(i).getString("description"));
            mainTextList.add(predsJsonArray.getJSONObject(i).getJSONObject("structured_formatting").getString("main_text"));

            if(predsJsonArray.getJSONObject(i).getJSONObject("structured_formatting").has("secondary_text"))
            {
                secondoryTextList.add(predsJsonArray.getJSONObject(i).getJSONObject("structured_formatting").getString("secondary_text"));
            }
            else{
                secondoryTextList.add("");
            }




        }
    } catch (JSONException e) {
        Log.e(LOG_TAG, "Cannot process JSON results", e);
    }

    return resultList;
}

答案 1 :(得分:0)

经过大量的研究和调试后,我解决了同样的问题。 您可以从here

获取帮助