Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autocompletetextview with custom adapter and filter

Tags:

android

I am trying to set a custom ArrayAdapter for my AutoCompleteTextView like this

public class AutoCompleteContactArrayAdapter extends
    ArrayAdapter<Map<String, String>> implements Filterable {
private Context mContext;
private List<Map<String, String>> mContactList;

public AutoCompleteContactArrayAdapter(Context context,
        List<Map<String, String>> objects) {
    super(context, R.layout.auto_contact_list, objects);
    mContext = context;
    mContactList = objects;
    // TODO Auto-generated constructor stub
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) mContext
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.auto_contact_list, parent,
            false);
    TextView nameView = (TextView) rowView.findViewById(R.id.ccontName);
    TextView phoneView = (TextView) rowView.findViewById(R.id.ccontNo);
    TextView typeView = (TextView) rowView.findViewById(R.id.ccontType);
    Map<String, String> contactMap = mContactList.get(position);

    nameView.setText(contactMap.get("name"));
    phoneView.setText(contactMap.get("phone"));
    typeView.setText(contactMap.get("type"));

    return rowView;
}
@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {

            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            ArrayList<String> result = new ArrayList<String>();
            result.add("test");
            result.add("another");
            result.add("last");
            FilterResults r = new FilterResults();
            r.values = result;
            r.count = result.size();
            return r;
        }
    };
}
}

In debug the application is entering the filter methods both publishResults() and performFiltering() but the result set that is being displayed is not my test array [test,another,last] instead it just shows all the results ignoring my filter.

like image 204
user1634451 Avatar asked May 28 '13 00:05

user1634451


People also ask

How do I create an AutoCompleteTextView field in XML?

In android, we can create an AutoCompleteTextView control in two ways either manually in an XML file or create it in the Activity file programmatically. First we create a new project by following the below steps: Click on File, then New => New Project. After that include the Kotlin support and click on next.

How do I set autocomplete text on Android?

If you want to get suggestions , when you type in an editable text field , you can do this via AutoCompleteTextView. It provides suggestions automatically when the user is typing. The list of suggestions is displayed in a drop down menu from which the user can choose an item to replace the content of the edit box with.

How to create custom adapter for autocompletetextview?

Autocompletetextview uses filter defined in the adapter to get results and show them. So, if you need to create custom adapter, you need to provide implementation for getView and provide a filter class. Show activity on this post.

What is autocompletetextview in Salesforce?

Autocompletetextview uses Adapter to show auto complete suggestion drop down. Adapater should be filterable and should give view populating data for each item from data list. Autocompletetextview uses filter defined in the adapter to get results and show them.

How to create autocompletetextview dropdown list in Android Studio?

1- Open Android Studio. Android studio 4.1.2 welcome screen. ( Large preview) 2- Next, open activity_main.xml file, and add the Android autocompletetextview. 3- Now open strings.xml file, and add the array that will populate the Android autocompletetextview dropdown.

How to create custom adapter for getview in Java?

So, if you need to create custom adapter, you need to provide implementation for getView and provide a filter class. Show activity on this post. then its wrong. You can do the same work as in form of ArrayList but remember you will never put here a Getter/Setter class.


2 Answers

Here is the current implementation of my code:

The xml

<AutoCompleteTextView
    android:id="@+id/searchAutoComplete"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"
    android:layout_marginRight="10dp"
    android:layout_toRightOf="@+id/linearLayout1"
    android:background="@drawable/abs__textfield_search_default_holo_light"
    android:drawableLeft="@drawable/abs__ic_search_api_holo_light"
    android:drawableRight="@drawable/abs__ic_clear_holo_light"
    android:hint="@string/search"
    android:imeOptions="actionSearch"
    android:inputType="textAutoComplete|textAutoCorrect" >

The adapter:

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;

public class AutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {

    private ArrayList<String> fullList;
    private ArrayList<String> mOriginalValues;
    private ArrayFilter mFilter;

    public AutoCompleteAdapter(Context context, int resource, int textViewResourceId, List<String> objects) {

        super(context, resource, textViewResourceId, objects);
        fullList = (ArrayList<String>) objects;
        mOriginalValues = new ArrayList<String>(fullList);

    }

    @Override
    public int getCount() {
        return fullList.size();
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return super.getView(position, convertView, parent);
    }

    @Override
    public Filter getFilter() {
        if (mFilter == null) {
            mFilter = new ArrayFilter();
        }
        return mFilter;
    }


    private class ArrayFilter extends Filter {
        private Object lock;

        @Override
        protected FilterResults performFiltering(CharSequence prefix) {
            FilterResults results = new FilterResults();

            if (mOriginalValues == null) {
                synchronized (lock) {
                    mOriginalValues = new ArrayList<String>(fullList);
                }
            }

            if (prefix == null || prefix.length() == 0) {
                synchronized (lock) {
                    ArrayList<String> list = new ArrayList<String>(mOriginalValues);
                    results.values = list;
                    results.count = list.size();
                }
            } else {
                final String prefixString = prefix.toString().toLowerCase();

                ArrayList<String> values = mOriginalValues;
                int count = values.size();

                ArrayList<String> newValues = new ArrayList<String>(count);

                for (int i = 0; i < count; i++) {
                    String item = values.get(i);
                    if (item.toLowerCase().contains(prefixString)) {
                        newValues.add(item);
                    }

                }

                results.values = newValues;
                results.count = newValues.size();
            }

            return results;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {

        if(results.values!=null){
        fullList = (ArrayList<String>) results.values;
        }else{
            fullList = new ArrayList<String>();
        }
            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    }
}

And finally in code initialize like this...

       ArrayList<String> searchArrayList= new ArrayList<String>();
//initilaze this array with your data
        AutoCompleteAdapter adapter = new AutoCompleteAdapter(this, android.R.layout.simple_dropdown_item_1line, android.R.id.text1, searchArrayList);
        autoCompleteTextView = (AutoCompleteTextView) customNav.findViewById(R.id.searchAutoComplete);
        autoCompleteTextView.setAdapter(adapter);

Done :)

like image 66
Ali Imran Avatar answered Sep 19 '22 08:09

Ali Imran


Okay i think i figure out what Luksprog was saying this code works now they key is this

mContactList = (ArrayList<Map<String, String>>) results.values;

in

@Override
public int getCount(){
    return mContactList.size();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) mContext
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.auto_contact_list, parent,
            false);
    TextView nameView = (TextView) rowView.findViewById(R.id.ccontName);
    TextView phoneView = (TextView) rowView.findViewById(R.id.ccontNo);
    TextView typeView = (TextView) rowView.findViewById(R.id.ccontType);
    Map<String, String> contactMap = mContactList.get(position);

    nameView.setText(contactMap.get("name"));
    phoneView.setText(contactMap.get("phone"));
    typeView.setText(contactMap.get("type"));

    return rowView;
}
@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {

            if (results.count > 0) {
                mContactList = (ArrayList<Map<String, String>>) results.values;
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            ArrayList<Map<String, String>> result = new ArrayList<Map<String, String>>();
            HashMap<String,String> myMap = new HashMap<String,String>();
            myMap.put("name", "key");
            result.add(myMap);
            HashMap<String,String> myMap2 = new HashMap<String,String>();
            myMap2.put("name", "is");
            result.add(myMap2);
            HashMap<String,String> myMap3 = new HashMap<String,String>();
            myMap3.put("name", "another");
            result.add(myMap3);
            FilterResults r = new FilterResults();
            r.values = result;
            r.count = result.size();
            return r;
        }
    };
}
like image 37
user1634451 Avatar answered Sep 18 '22 08:09

user1634451