Попытка отфильтровать ListView с помощью runQueryOnBackgroundThread, но ничего не происходит - что мне не хватает?
У меня есть список стран в базе данных. Я создал операцию по выбору страны, которая состоит из поля для фильтрации и списка, в котором отображается флаг и название страны.
Когда начинается действие, список показывает весь список стран, отсортированных по алфавиту - работает нормально. Когда клиент начинает вводить текст в поле поиска, я хочу, чтобы список был отфильтрован по типу ввода. Мой запрос к базе данных ранее работал в AutoCompleteView (я просто хочу переключиться на отдельное текстовое поле и список), поэтому я знаю, что мой полный запрос и мой запрос на ограничение работают. Что я сделал, так это добавил TextWatcher в представление EditText, и каждый раз, когда текст изменяется, я вызываю SimpleCursorAdapter списка runQueryOnBackgroundThread с текстом полей редактирования в качестве ограничения. Беда в том, что список никогда не обновляется. Я установил точки останова в отладчике, и TextWatcher делает вызов runQueryOnBackgroundThread, и мой FilterQueryProvider вызывается с ожидаемым ограничением. Запрос к базе данных проходит нормально, и курсор возвращается.
Адаптер курсора имеет установленный поставщик запроса фильтра (и средство просмотра для отображения флага):
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;
}
}
И EditText имеет 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
}
});
Запрос к базе данных выглядит так:
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's 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");
}
}
Просто кажется, что где-то отсутствует ссылка. Любая помощь будет оценена.
Спасибо,
Ян
2 ответа
Похоже, вы делаете большую работу для чего-то, что уже встроено в Android. Взгляните на диалог поиска Android по адресу http://developer.android.com/guide/topics/search/search-dialog.html, и он должен быть очень простым для вас.
Я видел, что вам удалось решить свою проблему по-другому, но подумал, что я должен добавить ответ для других людей, наткнувшихся на этот вопрос.
runQueryOnBackgroundThread() отвечает только за выполнение запроса для ограничения и возврат курсора. Чтобы фильтровать адаптер по курсору, нужно сделать что-то вроде
filterAdapter.getFilter().filter(s.toString());
CursorAdapter всегда реализует Filterable по умолчанию, и все, что реализует фильтруемость, может быть отфильтровано с помощью
getFilter(). фильтр (ограничение)
Способ, с помощью которого встроенный фильтр CursorAdapters работает, заключается в том, что если вы переопределите runQueryOnBackgroundThread() или используете setFilterQueryProvider(), то он выполнит этот код в фоновом потоке, получит новый курсор и установит его в качестве курсора CursorAdapter.