Попытка отфильтровать 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.

Другие вопросы по тегам