Dynamically updating an AutoCompleteTextView adapter Dynamically updating an AutoCompleteTextView adapter android android

Dynamically updating an AutoCompleteTextView adapter


I didn't have any luck using adapter.notifyDataSetChanged() when dynamically adding and changing the data in the adapter. In my situation, I was hitting an external api asynchronously and getting a list of completion data periodically.

This code clears the adapter, and adds the new data as you'd expect. However, I had to call the getFilter().Filter method to force the data to show. Also, I had to explicitly filter based on the current text in the AutocompleteTextView because my api call was asynchronous.

adapter.clear();for (Map<String, String> map : completions) {     adapter.add(map.get("name"));}//Force the adapter to filter itself, necessary to show new data.//Filter based on the current text because api call is asynchronous. adapter.getFilter().filter(autocompleteTextView.getText(), null);


This is how I update my AutoCompleteTextView:

String[] data = terms.toArray(new String[terms.size()]);  // terms is a List<String>ArrayAdapter<?> adapter = new ArrayAdapter<Object>(activity, android.R.layout.simple_dropdown_item_1line, data);keywordField.setAdapter(adapter);  // keywordField is a AutoCompleteTextViewif(terms.size() < 40) keywordField.setThreshold(1); else keywordField.setThreshold(2);

Now of course, this is static and doesn't deal with an over-the-air suggestions but, I can also suggest you to notify adapter for the changes after you assign it to the AutoCompleteTextView:

adapter.notifyDataSetChanged();   

Hope this helps.

-serkan


There was a pretty good tutorial on this topic using remote data in the Google Map API to populate a AutoCompleteTextView here.

If you need a cached version, I retrieved it from here.The original tutorial has been deleted, but essentially you need to write an ArrayAdapter with a custom filter in a similar way to that shown below and assign it to your AutoCompleteTextView.

Note: You need to implement a method autocomplete() that does whatever operation is required to synchronously fetch and return the autocompletion items. As the filter is invoked in a background thread, this will not block the main UI thread.

private class PlacesAutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {private ArrayList<String> resultList;public PlacesAutoCompleteAdapter(Context context, int textViewResourceId) {    super(context, textViewResourceId);}@Overridepublic int getCount() {    return resultList.size();}@Overridepublic String getItem(int index) {    return resultList.get(index);}@Overridepublic Filter getFilter() {    Filter filter = new Filter() {        @Override        protected FilterResults performFiltering(CharSequence constraint) {            FilterResults filterResults = new FilterResults();            if (constraint != null) {                // Retrieve the autocomplete results.                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, FilterResults results) {            if (results != null && results.count > 0) {                notifyDataSetChanged();            }            else {                notifyDataSetInvalidated();            }        }};    return filter;}}