androidautocompletetextviewsimplecursoradapter

AutoCompleteTextView with SimpleCursorAdapter does not filter


In my app, I have a few AutoCompleteTextView widgets that use an ArrayAdapter.

private List<String> adapterList = new ArrayList<String>();
ArrayAdapter<String> dropdownAdapter;
dropdownAdapter = new ArrayAdapter<>(getContext(), R.layout.simple_dropdown_item, adapterList);
autoCompleteTextView.setAdapter(dropdownAdapter);

It works beautifully. As I type into the View, I get words-starting-with results in the dropdown.

I want to do this with another AutoCompleteTextView, but this time using a SimpleCursorAdapter.

nameSearchCursor = dbHelper.getChecklistTabDataByChecklistId(outingId, checklistId, nameColumn);
NameSearch = root.findViewById(R.id.SearchNames);
String[] nsColumns = new String[]{nameColumn};
int[] nsTo = new int[]{R.id.simpleDropdownItem};
nameSearchCursorAdapter = new SimpleCursorAdapter(getContext(), R.layout.simple_dropdown_item,
        nameSearchCursor, nsColumns, nsTo, 0);
NameSearch.setAdapter(nameSearchCursorAdapter);

If I start typing in this new View, the dropdown appears and shows the entire list, and nothing changes as I type. No filtering occurs. What do I need to do differently (and perhaps why) to get a CursorAdapter to work with this View that I didn't need to do when using an ArrayAdapter. I have searched this site and read the Developer Docs and there must be something I just don't get. Please enlighten me.


Solution

  • This site allowed me to answer this question: http://www.outofwhatbox.com/blog/2010/11/android-simpler-autocompletetextview-with-simplecursoradapter/

    Here is my completed code:

    private void setUpNameSearch() {
        // Get AutoCompleteTextView
        nameSearchView = root.findViewById(R.id.SearchNames);
        // Define from/to info
        final String[] nsColumns = new String[]{nameColumn};
        final int[] nsTo = new int[]{R.id.simpleDropdownItem};
        // Create adapter. Cursor set in setFilterQueryProvider() below.
        nameSearchCursorAdapter = new SimpleCursorAdapter(getContext(), R.layout.simple_dropdown_item,
                null, nsColumns, nsTo, 0);
        // Set adapter on view.
        nameSearchView.setAdapter(nameSearchCursorAdapter);
    
        // OnItemClickListener - User selected value from DropDown
        nameSearchView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> listView, View view, int position, long id) {
                // Get the cursor. Positioned to the corresponding row in the result set.
                Cursor cursor = (Cursor) listView.getItemAtPosition(position);
                // Get the name selected
                String selectedName = cursor.getString(cursor.getColumnIndexOrThrow(nameColumn));
                // Do something with this value...
            }
        });
    
        // Set the CursorToStringconverter, to provide the values for the choices to be displayed
        // in the AutoCompleteTextview.
        nameSearchCursorAdapter.setCursorToStringConverter(new SimpleCursorAdapter.CursorToStringConverter() {
            @Override
            public CharSequence convertToString(Cursor cursor) {
                final String name = cursor.getString(cursor.getColumnIndexOrThrow(nameColumn));
                return name;
            }
        });
    
        // Set the FilterQueryProvider, to run queries for choices
        nameSearchCursorAdapter.setFilterQueryProvider(new FilterQueryProvider() {
            @Override
            public Cursor runQuery(CharSequence constraint) {
                Cursor cursor = dbHelper.getMatchingNames(outingId, checklistId, nameColumn,
                        (constraint != null ? constraint.toString() : null));
                return cursor;
            }
        });
    }
    

    I wanted to duplicate the word-starting-with default functionality of the AutoCompeteTextView using the SQLite Cursor, only to find that REGEXP are not fully supported. So this StackOverflow topic gave me the LIKE workaround. SQLite LIKE alternative for REGEXP, Match Start of Any Word

    I hope this helps others.