Trying to filter a ListView using runQueryOnBackgroundThread, but nothing happens - what am I missing?

I have a list of countries in the database. I created a country selection operation, which consists of an editing window for filtering and a list that displays the flag and the name of the country.

When activity begins, the list shows the entire list of countries sorted alphabetically - it works fine. When the client starts typing in the search box, I want the list to be filtered based on their input. My database query previously worked in AutoCompleteView (I just want to switch to a separate text box and list), so I know that my full query and my restriction query work. What I did was add a TextWatcher to the EditText view, and each time the text changes, I call the SimpleCursorAdapter runQueryOnBackgroundThread list with the text of the edit field as a constraint. The problem is that the list is never updated. I set breakpoints in the debugger, and TextWatcher makes a call to runQueryOnBackgroundThread, and my FilterQueryProvider is called with the expected limit. The database query stops and the cursor returns.

The cursor adapter has a set of filter request providers (and a link image for displaying the flag):

SimpleCursorAdapter adapter = new SimpleCursorAdapter (this, R.layout.country_list_row, countryCursor, from, to); adapter.setFilterQueryProvider (new CountryFilterProvider ()); adapter.setViewBinder (new FlagViewBinder ()); 

FitlerQueryProvider:

 private final class CountryFilterProvider implements FilterQueryProvider { @Override public Cursor runQuery (CharSequence constraint) { Cursor countryCursor = myDbHelper.getCountryList (constraint); startManagingCursor (countryCursor); return countryCursor; } } 

And EditText has a TextWatcher:

  myCountrySearchText = (EditText)findViewById (R.id.entry); myCountrySearchText.setHint (R.string.country_hint); myCountrySearchText.addTextChangedListener (new TextWatcher() { @Override public void afterTextChanged (Editable s) { SimpleCursorAdapter filterAdapter = (SimpleCursorAdapter)myCountryList.getAdapter (); filterAdapter.runQueryOnBackgroundThread (s.toString ()); } @Override public void onTextChanged (CharSequence s, int start, int before, int count) { // no work to do } @Override public void beforeTextChanged (CharSequence s, int start, int count, int after) { // no work to do } }); 

The query for the database is as follows:

 public Cursor getCountryList (CharSequence constraint) { if (constraint == null || constraint.length () == 0) { // Return the full list of countries return myDataBase.query (DATABASE_COUNTRY_TABLE, new String[] { KEY_ROWID, KEY_COUNTRYNAME, KEY_COUNTRYCODE }, null, null, null, null, KEY_COUNTRYNAME); } else { // Return a list of countries who name contains the passed in constraint return myDataBase.query (DATABASE_COUNTRY_TABLE, new String[] { KEY_ROWID, KEY_COUNTRYNAME, KEY_COUNTRYCODE }, "Country like '%" + constraint.toString () + "%'", null, null, null, "CASE WHEN Country like '" + constraint.toString () + "%' THEN 0 ELSE 1 END, Country"); } } 

There seems to be a link somewhere missing. Any help would be appreciated.

Thanks,

Yang

+6
android listview
source share
2 answers

It seems that you are working a lot on what is already built into Android. Take a look at the Android Search Dialog at http://developer.android.com/guide/topics/search/search-dialog.html and this should be very easy for you.

+3
source share

I saw that you managed to solve your problem differently, but I thought that I should add an answer to other people who stumble on this question.

runQueryOnBackgroundThread () is only responsible for executing the query to limit and returning the cursor. To be able to filter the adapter based on the cursor, you need to do something like

 filterAdapter.getFilter().filter(s.toString()); 

A CursorAdapter always implements Filterable by default, and anything that implements filtering can be filtered using

  getFilter (). filter (constraint) 

The way to create CursorAdapters in a filter is that if you override runQueryOnBackgroundThread () or use setFilterQueryProvider (), then it runs this code in the background thread, gets a new cursor and sets it as CursorAdapter cursor.

+15
source share

All Articles