【问题标题】:How to filter results of AutoCompleteTextView?如何过滤 AutoCompleteTextView 的结果?
【发布时间】:2011-06-09 23:40:22
【问题描述】:

我有一个 AutoCompleteTextView 设置为使用一个游标在我的联系人上。问题是,我让它正确填充下拉列表,但在我输入后它没有过滤结果。

这是我的光标和适配器设置的代码:

edt_Contact = (AutoCompleteTextView)findViewById(R.id.compose_edtContact);

cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
        new String[] {Phone._ID, Phone.DISPLAY_NAME, Phone.NUMBER}, 
        null,null,null);
startManagingCursor(cursor);
String[] from = new String[] { Phone.DISPLAY_NAME, Phone.NUMBER};
int[] to = new int[] { R.id.contact_name, R.id.contact_phoneNo};
adapter = new SimpleCursorAdapter(this, R.layout.simple_contact_textview, cursor, from, to);

edt_Contact.setAdapter(adapter);

这里是 simple_contact_textview 的 xml:

<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent" android:padding="5sp" android:paddingBottom="5sp" android:background="#FFFFFFFF">
    <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:id="@+id/contact_name" 
        android:textColor="#FF000000" 
        android:textSize="20sp" 
        android:text="Name">
    </TextView>
    <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:id="@+id/contact_phoneNo" 
        android:paddingLeft="10sp" 
        android:textColor="#FF000000" 
        android:textSize="20sp" 
        android:text="Number" 
        android:ellipsize="end">
    </TextView>
</LinearLayout>

如何根据用户输入的内容过滤下拉结果?例如,如果用户开始输入“and”,我将如何出现“andrew”、“andy”和“mandy”?

【问题讨论】:

标签: android autocompletetextview


【解决方案1】:

构造一个FilterQueryProvider 并将其传递给adapter.setFilterQueryProvider()

adapter.setFilterQueryProvider(new FilterQueryProvider() {
    public Cursor runQuery(CharSequence constraint) {
        String s = '%' + constraint.toString() + '%';
        return getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
            new String[] {Phone._ID, Phone.DISPLAY_NAME, Phone.NUMBER},
            Phone.DISPLAY_NAME + ' LIKE ? OR ' + Phone.NUMBER + ' LIKE ?',
            new String[] { s, s },
            null);
    }
});

上面的代码将返回匹配字符串中任何位置的结果(不仅仅是在开头。此外,由于它使用参数化查询,您的用户将无法通过 SQL 注入攻击破坏数据库。

(不在实际计算机附近,所以我无法测试上述内容——可能存在一些语法错误。)

【讨论】:

  • 是的,这就是我最终要做的。谢谢老兄!
  • 知道为什么 constraint.toString() 会导致 NPE 被抛出并被 CursorFilter.performFiltering 捕获,即使约束在 runQuery 中不为空?
【解决方案2】:

终于尝试了一些可行的方法:

private void initViews() {

    edt_Contact = (AutoCompleteTextView)findViewById(R.id.compose_edtContact);

    cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
            new String[] {Phone._ID, Phone.DISPLAY_NAME, Phone.NUMBER}, 
            null,null,null);
    startManagingCursor(cursor);
    String[] from = new String[] { Phone.DISPLAY_NAME, Phone.NUMBER};
    int[] to = new int[] { R.id.contact_name, R.id.contact_phoneNo};
    adapter = new SimpleCursorAdapter(this, R.layout.simple_contact_textview, cursor, from, to);

    adapter.setFilterQueryProvider(new FilterQueryProvider() {
        public Cursor runQuery(CharSequence constraint) {
            return getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
                    new String[] {Phone._ID, Phone.DISPLAY_NAME, Phone.NUMBER}, 
                    Phone.DISPLAY_NAME + " LIKE '" + constraint + "%'", 
                    null, null);
        }
    });

    edt_Contact.setAdapter(adapter);
}

对不起,如果我抢了任何人的答案。像这样的所有问题,似乎都有很低的看法和答案……

【讨论】:

  • 没问题。 SO 在我提交之前告诉我还有另一个答案,但看起来你在我准备提交之前几分钟就回答了。不知道为什么花了这么长时间才通知我有另一个答案。
猜你喜欢
  • 2020-05-01
  • 1970-01-01
  • 2013-10-06
  • 1970-01-01
  • 2012-01-20
  • 2020-01-31
  • 2019-05-15
  • 2017-05-03
  • 1970-01-01
相关资源
最近更新 更多