试图用runQueryOnBackgroundThread过滤ListView但没有任何反应 - 我错过了什么?

时间:2010-12-31 17:24:55

标签: android listview

我有一个数据库中的国家/地区列表。我创建了一个选择国家/地区活动,其中包含一个用于过滤的编辑框和一个显示标记和国家/地区名称的列表。

当活动开始时,列表显示按字母顺序排序的整个国家/地区列表 - 工作正常。当客户开始在搜索框中输入内容时,我希望根据他们的输入过滤列表。我的数据库查询以前在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");
    }
}

似乎某处缺少某个链接。任何帮助将不胜感激。

谢谢,

伊恩

2 个答案:

答案 0 :(得分:15)

我看到你设法以另一种方式解决了你的问题,但我想我应该为其他人绊倒这个问题添加答案。

runQueryOnBackgroundThread()仅负责运行约束的查询并返回Cursor。为了能够根据光标过滤适配器,您需要执行类似

的操作
filterAdapter.getFilter().filter(s.toString());

默认情况下,CursorAdapter始终实现Filterable,并且可以使用

getFilter().filter(constraint)

过滤实现可过滤的任何内容。

CursorAdapters在过滤器中构建的方式是,如果您重写runQueryOnBackgroundThread()或者使用setFilterQueryProvider(),那么它在后台线程中运行该代码,获取一个新游标并将其设置为CursorAdapter的。

答案 1 :(得分:3)

对于已内置于Android中的内容,您似乎正在做很多工作。请查看http://developer.android.com/guide/topics/search/search-dialog.html处的Android搜索对话框,它应该非常简单。