Skip to content Skip to sidebar Skip to footer

Autocompletetextview With Custom Adapter And Filter

I am trying to set a custom ArrayAdapter for my AutoCompleteTextView like this public class AutoCompleteContactArrayAdapter extends ArrayAdapter&g

Solution 1:

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;

publicclassAutoCompleteAdapterextendsArrayAdapter<String> implementsFilterable {

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

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

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

    }

    @OverridepublicintgetCount() {
        return fullList.size();
    }

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

    @Overridepublic View getView(int position, View convertView, ViewGroup parent) {
        returnsuper.getView(position, convertView, parent);
    }

    @Overridepublic Filter getFilter() {
        if (mFilter == null) {
            mFilter = newArrayFilter();
        }
        return mFilter;
    }


    privateclassArrayFilterextendsFilter {
        private Object lock;

        @Overrideprotected FilterResults performFiltering(CharSequence prefix) {
            FilterResultsresults=newFilterResults();

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

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

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

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

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

                }

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

            return results;
        }

        @SuppressWarnings("unchecked")@OverrideprotectedvoidpublishResults(CharSequence constraint, FilterResults results) {

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

And finally in code initialize like this...

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

Done :)

Solution 2:

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

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

@OverridepublicViewgetView(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;
}
@OverridepublicFiltergetFilter() {
    returnnewFilter() {
        @OverrideprotectedvoidpublishResults(CharSequence constraint,
                FilterResults results) {

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

        @OverrideprotectedFilterResultsperformFiltering(CharSequence constraint) {
            ArrayList<Map<String, String>> result = newArrayList<Map<String, String>>();
            HashMap<String,String> myMap = newHashMap<String,String>();
            myMap.put("name", "key");
            result.add(myMap);
            HashMap<String,String> myMap2 = newHashMap<String,String>();
            myMap2.put("name", "is");
            result.add(myMap2);
            HashMap<String,String> myMap3 = newHashMap<String,String>();
            myMap3.put("name", "another");
            result.add(myMap3);
            FilterResults r = newFilterResults();
            r.values = result;
            r.count = result.size();
            return r;
        }
    };
}

Solution 3:

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.

So, if you need to create custom adapter, you need to provide implementation for getView and provide a filter class.

Complete working example of autocompletetextview custom layout and custom adapter

http://www.zoftino.com/android-autocompletetextview-custom-layout-and-adapter

Solution 4:

if you are wanna add the data in

String[] arr=new String[100];

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. Just simply declare it. See this example.

Declare in main partition:

ArrayList<String>arr=newArrayList<>();

and then initilize it in this way:

for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject1 = (JSONObject) jsonArray.get(i);
                String imei = jsonObject1.getString("imei");
                String name = jsonObject1.getString("name");
                String my_pic = jsonObject1.getString("my_pic");
                String email = jsonObject1.getString("email");

                arr.add(name);
            }


            adapter= newArrayAdapter<>
                    (this, android.R.layout.select_dialog_item, arr);
            autoCompleteText.setThreshold(1);//will start working from first character
            autoCompleteText.setAdapter(adapter);//setting the adapter data into the AutoCompleteTextView
            autoCompleteText.setTextColor(Color.RED);


        }

I hope this will work for you. Best of luck

Solution 5:

Anyone who interested in Kotlin version you may find below.

val ac = findViewById<AutoCompleteTextView>(R.id.searchAutoComplete)
var dataList = listOf("argument", "aid", "appear", "air", "advertise", "appendix", "apathy", "absence", "analysis",
    "bind", "bathroom", "broadcast", "bomb", "build", "bark", "beef", "brain", "bend",
    "conviction", "coincide", "castle", "cafe", "chemistry", "clean", "closed", "composer", "care", "crude")
ac.setAdapter(object : ArrayAdapter<String>(
    context, android.R.layout.simple_dropdown_item_1line, android.R.id.text1, dataList,
), Filterable {
    privatevar oriValue = dataList.toList()
    overridefungetCount() = dataList.size
    overridefungetItem(position: Int) = dataList[position]
    overridefungetFilter() = object : Filter() {
        overridefunperformFiltering(prefix: CharSequence?) =
            FilterResults().apply {
                mutableListOf<String>().apply {
                    if (prefix == null || prefix.isEmpty()) addAll(oriValue)
                    else oriValue.map {
                        if (it.contains(prefix.toString(), true)) // ignore case// if (it.contains(prefix.toString())) // match case// if (it.startsWith(prefix.toString(), true)) // start with
                            add(it)
                    }
                    values = this
                    count = this.size
                }
            }
        overridefunpublishResults(constraint: CharSequence?, results: FilterResults?) {
            @Suppress("UNCHECKED_CAST")
            dataList = results?.values as List<String>? ?: listOf()
            if (results?.count ?: -1 > 0) notifyDataSetChanged() 
            else notifyDataSetInvalidated()
        }
    }
})

Post a Comment for "Autocompletetextview With Custom Adapter And Filter"