Search code examples
androidxamarinxamarin.formsxamarin.androidautocompletetextview

Autocomplete Text Input only shows items that matches to the first letter only


I am using Autocomplete Text Input control of xamain. Autocomplete reference

Here is my code

var autoCompleteOptions = GetAllContacts();
ArrayAdapter autoCompleteAdapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleDropDownItem1Line, autoCompleteOptions);
speedSearch = FindViewById<AutoCompleteTextView>(Resource.Id.AutoCompleteInput);
speedSearch.Adapter = autoCompleteAdapter;

Problem is when i try to search in my contacts, i only get the suggested values that matches the first letter only. for example if [paul@email.com, tom@email.com,bill@xamarin.com] is the list of contacts, if i make search with "xamarin" Autocomplete does not returns anything, but if i search with "bill" it will return. How can i change an autocompelte's behavior so that any part of string in an array item is searched, it should be returned.


Solution

  • You need create a custom adapter and implement IFilterable.

    Here is the source code of ArrayAdapter( java codes), you can find these codes in ArrayFilter.performFiltering():

    if (valueText.startsWith(prefixString)) {
        newValues.add(value);
    } else {
        final String[] words = valueText.split(" ");
        for (String word : words) {
            if (word.startsWith(prefixString)) {
                newValues.add(value);
                break;
            }
        }
    }
    

    Note startsWith, that is why you can't get "bill@xamarin.com" while you input "xa". You need change it to Contains.


    Here is a fast way to achieve your goal.

    Here is a class--AutoAdapter (C# codes) which has already implemented ArrayAdapter and IFilterable.

    You just need copy and paste it, and then replace:

                var matches = from i in a.AllItems
                            where i.IndexOf(searchFor) >= 0
                            select i;
    

    with:

                var matches = from i in a.AllItems
                              where i.Contains(searchFor)
                              select i;
    

    And at last, use AutoAdapter in your MainActivity:

        AutoCompleteTextView textView = FindViewById<AutoCompleteTextView>(Resource.Id.autocomplete_country);
        var adapter = new AutoAdapter(this, Resource.Layout.list_item, COUNTRIES);
        textView.Threshold=1;
        textView.Adapter = adapter;
    

    Note:

    You also need to look at performFiltering and publishResults methods in Filter class