尝试使用runQueryOnBackgroundThread过滤ListView,但没有任何反应 - 我漏掉了什么?

6

我在数据库中有一个国家列表。 我创建了一个选择国家的活动,包括一个用于过滤的编辑框和一个显示旗帜和国家名称的列表。

当活动开始时,列表按字母顺序显示整个国家列表 - 运行良好。 当用户开始在搜索框中输入时,我希望根据他们的输入筛选列表。 我之前在AutoCompleteView中使用过我的数据库查询(我只想切换到单独的文本框和列表),所以我知道我的完整查询和约束查询是可用的。 我所做的是在EditText视图中添加TextWatcher,并且每次更改文本时,我使用编辑框的文本作为约束调用列表的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");
    }
}

似乎有一些遗漏的地方,需要找到这个遗漏的环节。非常感谢您的帮助。

谢谢,

Ian


你为什么要在EditText中使用TextWatcher而不是AutoCompleteTextView? - IgorGanapolsky
如果您想为用户提供在ListView中滚动和过滤的选项,该怎么办呢?据我所知,AutoCompleteTextView不允许您拥有单独的ListView。 - rohitmishra
2个回答

15

我看到你已经通过其他方法解决了问题,但是我觉得我应该为其他遇到这个问题的人添加答案。

runQueryOnBackgroundThread() 只负责运行一个约束条件下的查询并返回 Cursor。如果要根据 Cursor 过滤适配器,则需要执行类似以下操作:

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

默认情况下,CursorAdapter始终通过实现Filterable接口,而任何实现了filterable接口的内容都可以使用

getFilter().filter(constraint)
进行过滤。

CursorAdapter内置的过滤器工作方式是,如果你重写runQueryOnBackgroundThread()方法或使用setFilterQueryProvider()方法,则在后台线程中运行该代码,获取新的游标并将其设置为CursorAdapter的游标。


谢谢你提供的信息,我很感激,并且我相信我以后一定会用到它。 - Ian Leslie

3

太棒了 - 我最初的问题仍然有点神秘,但你建议使用内置的搜索功能确实是正确的方法。我将这个实现添加到我的应用程序中,效果非常好。现在我正在研究内容提供者,以便在搜索过程中提供建议,并更好地集成到系统中。谢谢! - Ian Leslie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接