Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a custom adapter to an AutoCompleteTextView

Tags:

android

Is there any simple way to set a 2 TextView dropdown to an AutoCompleteTextView.

There is android.R.layout.two_line_list_item Which I couldn't find any examples how to use.

So, I tried this:

public class TwoLineDropdownAdapter extends BaseAdapter {

    private LayoutInflater mInflater = null;
    private Activity activity;
    public ArrayList<TwoLineDropDown> values = new ArrayList<TwoLineDropDown>();

    public TwoLineDropdownAdapter(Activity a, ArrayList<TwoLineDropDown> items) {

        values = items;
        activity = a;
        mInflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public int getCount() {

        return values.size();
    }

    public TwoLineDropDown getItem(int position) {

        return values.get(position);
    }

    public long getItemId(int position) {

        return position;
    }

    public static class ViewHolder {

        public TextView title;
        public TextView description;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {

        ViewHolder holder;

        if (convertView == null) {

            holder = new ViewHolder();

            convertView = mInflater.inflate(R.layout.dropdown_text_twoline,
                    parent, false);
            holder.title = (TextView) convertView
                    .findViewById(R.id.text1);
            holder.description = (TextView) convertView
                    .findViewById(R.id.text2);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        return convertView;
    }

    public void add(TwoLineDropDown ei) {

        values.add(ei);
    }
}

But I face a problem here:

TwoLineDropdownAdapter AutoCompleteAdapter = new TwoLineDropdownAdapter(this, items);
myAutoComplete.setAdapter(AutoCompleteAdapter);

while setting the Adapter it says:

Bound mismatch: The generic method setAdapter(T) of type AutoCompleteTextView is not applicable for the arguments (TwoLineDropdownAdapter). The inferred type TwoLineDropdownAdapter is not a valid substitute for the bounded parameter

How to solve this?

Thank You

like image 773
user1537779 Avatar asked Jun 06 '13 12:06

user1537779


1 Answers

Converted Dwivedi Ji's answer to Kotlin. I had some issue with Android Studio's auto convert. Thus, spent some time to make it work.

Now it is working. In case anyone needs it (in my case, I am filtering street names):

class StreetsAdapter( private val mContext: Context,
                      private val viewResourceId: Int,
                      private val items: ArrayList<Street>) : ArrayAdapter<Street?>(mContext, viewResourceId, items.toList()) {

    private val itemsAll = items.clone() as ArrayList<Street>
    private var suggestions = ArrayList<Street>()

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        var v: View? = convertView
        if (v == null) {
            val vi = mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            v = vi.inflate(viewResourceId, null)
        }
        val street: Street? = items[position]
        if (street != null) {
            val streetTitle = v?.findViewById(R.id.tvStreetTitle) as TextView?
            streetTitle?.text = street.title
        }
        return v!!
    }

    override fun getFilter(): Filter {
        return nameFilter
    }

    private var nameFilter: Filter = object : Filter() {
        override fun convertResultToString(resultValue: Any): String {
            return (resultValue as Street).title
        }

        override fun performFiltering(constraint: CharSequence?): FilterResults {
            return if (constraint != null) {
                suggestions.clear()
                for (street in itemsAll) {
                    if (street.title.toLowerCase().startsWith(constraint.toString().toLowerCase())) {
                        suggestions.add(street)
                    }
                }
                val filterResults = FilterResults()
                filterResults.values = suggestions
                filterResults.count = suggestions.size
                filterResults
            } else {
                FilterResults()
            }
        }

        override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
            val filteredList =  results?.values as ArrayList<Street>?

            if (results != null && results.count > 0) {
                clear()
                for (c: Street in filteredList ?: listOf<Street>()) {
                    add(c)
                }
                notifyDataSetChanged()
            }
        }
    }
}

And set your adapter:

val adapter = StreetsAdapter(this,
       R.layout.item_street, //Your layout. Make sure it has [TextView] with id "tvStreetTitle" 
       arrayListOf() //Your list goes here
)
autoTextView.threshold = 1 //will start working from first character
autoTextView.setAdapter(adapter)
like image 175
Azizjon Kholmatov Avatar answered Oct 05 '22 04:10

Azizjon Kholmatov