AutoCompleteTextView backed with data from SQLite in Android


This is a handy piece of code. As your database gets bigger you can allow the user to pick the correct value by typing. If the db gets very big, you can always increase the threshold, so that the query does not run until there will be a suitably sized resultset returned. Running it at a threshold of 1 is fine for very small resultsets. 
Here is the code you need to back your AutoCompleteTextView with a cursor adapter.


@Override
protected void onResume() {
super.onResume();


text = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1);
final AdapterHelper h = new AdapterHelper(this);


Cursor c = h.getAllResults();
startManagingCursor(c);
String[] from = new String[] { "val" };
int[] to = new int[] { android.R.id.text1 };
CursorAdapter adapter = new MyCursorAdapter(this,
android.R.layout.simple_dropdown_item_1line, c,
from, to);


adapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
if (constraint == null) {
return h.getAllResults();
}
String s = '%' + constraint.toString() + '%';
return h.getAllResults(s);
}
});


text.setAdapter(adapter);
}


class MyCursorAdapter extends SimpleCursorAdapter {


public MyCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);


}


public CharSequence convertToString(Cursor cursor) {
return cursor.getString(cursor.getColumnIndex("val"));
}


}



The database that I am using has 3k rows of data in it and the Autocomplete works fine. 
The things to note are that you need make sure that the your adapter puts the correct value in the text box once a user selects it. Do this with the convertToString method (at the end of the snippet above). You get to this method by extending SimpleCursorAdapter and overriding the method as shown.
Then you need to provide a FilterQueryProvider to your adapter. This allows your query to be run with the where clause of your typed text. 

Comments

  1. Hi nice demo, almost the same as what I came up with. Only question I have is that in the runQuery on the filter a new Cursor is obtained, how is this ever closed. The adaptor has a changeCursor() method which I thought might be of some use however this throws an exception because the observers of the original cursor are notified its changed and this is not from the same gui thread, its the background thread!

    I have the same issue in my code.

    ReplyDelete
  2. Sorry forget my previous question, I now note from reading the javadoc that the cursor returned from the runQuery on the filter is managed correctly and any previous cursor held by the adaptor is closed :)

    ReplyDelete

Post a Comment

Popular posts from this blog

Building a choropleth map for Irish agricultural data

Early Stopping with Keras