如何过滤AutoCompleteTextView的结果?

9

我有一个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”出现?


我正在这里做类似的事情!!! https://dev59.com/Y-o6XIcBkEYKwwoYPR_f - Etienne Lawlor
2个回答

11

构建一个 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注入攻击来损坏数据库。

(由于不在实际计算机附近,因此无法测试上述代码 - 可能存在一些语法错误。)


是的,这就是我最终做的。谢谢伙计! - John Leehey
你有没有想过为什么在runQueryconstraint不为空,但在CursorFilter.performFiltering中调用constraint.toString()会导致NPE被抛出和捕获? - theblang

1
终于尝试了一些有效的东西:
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告诉我在我提交答案之前有另一个答案,但看起来你在我准备提交之前回答了好几分钟。不确定为什么通知我有另一个答案可用要花这么长时间。 - Steve Prentice

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