Bluemarble
Bluemarble

Reputation: 2059

How to bind AutoCompleteTextView from a list of two-string object?

I have an autocomplete text box in my layout and I am using a custom adapter to populate the autocomplete suggestions.

AutoCompleteTextView autocompleteView = (AutoCompleteTextView) findViewById(R.id.autocomplete);
autocompleteView.setAdapter(new PlacesAutoCompleteAdapter(context, R.layout.autocomplete_list_item));

when a suggestion is tapped, the selected value is shown in a Toast.

autocompleteView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                
            String description = (String) parent.getItemAtPosition(position);
            Toast.makeText(context, description, Toast.LENGTH_SHORT).show();
        }
    });

Here is my custom adapter class. I have marked the place where my method is returning a List of String.

public class PlacesAutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {

ArrayList<String> resultList;
Context mContext;
int mResource;

public PlacesAutoCompleteAdapter(Context context, int resource) {
    super(context, resource);
    mContext = context;
    mResource = resource;
}

@Override
public int getCount() {
    // Last item will be the footer
    return resultList.size();
}

@Override
public String getItem(int position) {
    return resultList.get(position);
}


@Override
public Filter getFilter() {
    Filter filter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new Filter.FilterResults();
            if (constraint != null) {

            resultList = /##### HERE IS MY METHOD WHICH RETURNS A LIST OF STRING #####/

                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;
   }
}

This works fine. But I need to change the adapter such a way so that it returns a two dimensional array of strings.

my intention is to return a set of [name][ID] pair to the autocomplete box. I have already written a class for this purpose.

public class autoCompleteItem {
public String placeName;
public String placeID;
}

instead of returning a linear list of strings, I have modified my data-fetching method to return a list of autoCompleteItem objects. but I am not able to bind this to my autocomplete text box.

What I want to achieve is:

  1. The autocomplete box will display suggestions from the list of autoCompleteItem objects for placeName only. (i.e. the suggestion will not show the placeID)

  2. When a suggestion is tapped, I want the placeID to be shown on the toast.

Upvotes: 1

Views: 4417

Answers (1)

Blackbelt
Blackbelt

Reputation: 157457

using a model's class is the correct way. You will have, of course, to change your Adapter. You will have to extend extends ArrayAdapter<autoCompleteItem> instenad of ArrayAdapter<String>. The same is for getItem, which has to return autoCompleteItem instenad of String. You will have to change also ArrayList<String> resultList in ArrayList<autoCompleteItem> resultList.

Since your are not overriding getView(), override getString in your model's class and let it return placeName

In your onItemClick you will need

  autoCompleteItem item = (autoCompleteItem) parent.getItemAtPosition(position);

and the you can access the autoCompleteItem's member trough item.

As small note, autoCompleteItem should be AutoCompleteItem accordingly to the java naming conventions . E.g

public class AutoCompleteItem {
     public String placeName; 
     public String placeID;

  @Override
  public String toString() {
     return placeName;
  }
}

Upvotes: 4

Related Questions