通过Android中的TextWatcher过滤联系人列表

通过Android中的TextWatcher过滤联系人列表,android,filtering,simplecursoradapter,textwatcher,Android,Filtering,Simplecursoradapter,Textwatcher,我正在列表视图中显示联系人,并尝试使用EditText筛选相同的列表。但是当我输入一些东西时,过滤不会发生,尽管输入的文本是以Logcat的形式出现的。 以下是我的onCreate: public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_invite); EditText filter

我正在列表视图中显示联系人,并尝试使用EditText筛选相同的列表。但是当我输入一些东西时,过滤不会发生,尽管输入的文本是以Logcat的形式出现的。 以下是我的onCreate:

public void onCreate(Bundle savedInstanceState) {


    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_invite);
    EditText filterText = findViewById(R.id.search_box);

    filterText.addTextChangedListener(filterTextWatcher);

    // The contacts from the contacts content provider is stored in this cursor
    mMatrixCursor = new MatrixCursor(new String[]{"_id", "name", "details"});

    // Adapter to set data in the listview
    mAdapter = new SimpleCursorAdapter(getBaseContext(),
            R.layout.contact_layout, null, new String[]{"name", "details"}, new int[]{R.id.tv_name, R.id.tv_details}, 0);

    // Getting reference to listview
    ListView lstContacts = findViewById(R.id.lst_contacts);

    // Setting the adapter to listview
    lstContacts.setAdapter(mAdapter);

    // Creating an AsyncTask object to retrieve and load listview with contacts
    ListViewContactsLoader listViewContactsLoader = new ListViewContactsLoader();

    // Starting the AsyncTask process to retrieve and load listview with contacts
    listViewContactsLoader.execute();

}
这是我的TextWatcher:

private TextWatcher filterTextWatcher = new TextWatcher() {

    public void afterTextChanged(Editable s) {
    }

    public void beforeTextChanged(CharSequence s, int start, int count,
                                  int after) {
    }

    public void onTextChanged(CharSequence s, int start, int before,
                              int count) {
        Log.d(TAG, "onTextChanged: " + s);
        mAdapter.getFilter().filter(s.toString());
    }

};
我做错了什么?有人能帮忙吗

编辑:添加我的ListViewContactsLoader

private class ListViewContactsLoader extends AsyncTask<Void, Void, Cursor> {

    @Override
    protected Cursor doInBackground(Void... params) {
        Uri contactsUri = ContactsContract.Contacts.CONTENT_URI;

        // Querying the table ContactsContract.Contacts to retrieve all the contacts
        Cursor contactsCursor = getContentResolver().query(contactsUri,
                null, null, null,
                ContactsContract.Contacts.DISPLAY_NAME + " ASC ");

        if (contactsCursor.moveToFirst()) {
            do {
                long contactId = contactsCursor.getLong(contactsCursor
                        .getColumnIndex("_ID"));

                Uri dataUri = ContactsContract.Data.CONTENT_URI;

                // Querying the table ContactsContract.Data to retrieve individual items like
                // home phone, mobile phone etc corresponding to each contact
                Cursor dataCursor = getContentResolver().query(dataUri,
                        null,
                        ContactsContract.Data.CONTACT_ID + "=" + contactId,
                        null, null);

                String displayName = "";
                String mobilePhone = "";

                if (dataCursor.moveToFirst()) {
                    // Getting Display Name
                    displayName = dataCursor
                            .getString(dataCursor
                                    .getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
                    do {
                        // Getting Phone numbers
                        if (dataCursor
                                .getString(
                                        dataCursor
                                                .getColumnIndex("mimetype"))
                                .equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
                            switch (dataCursor.getInt(dataCursor
                                    .getColumnIndex("data2"))) {
                                case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE:
                                    mobilePhone = dataCursor
                                            .getString(dataCursor
                                                    .getColumnIndex("data1"));
                                    break;
                            }
                        }

                    } while (dataCursor.moveToNext());

                    String details = "";

                    // Concatenating various information to single string
                    if (mobilePhone != null && !mobilePhone.equals(""))
                        details = mobilePhone + "\n";

                    // Adding id, display name, path to photo and other details to cursor
                    mMatrixCursor.addRow(new Object[]{
                            Long.toString(contactId), displayName, details});
                }

            } while (contactsCursor.moveToNext());
        }
        return mMatrixCursor;
    }

    @Override
    protected void onPostExecute(Cursor result) {
        // Setting the cursor containing contacts to listview
        mAdapter.swapCursor(result);
        Log.d(TAG, "onPostExecute: " + result);
    }
}
私有类ListViewContactsLoader扩展异步任务{
@凌驾
受保护的游标doInBackground(无效…参数){
Uri contactsUri=ContactsContract.Contacts.CONTENT\u Uri;
//查询ContactsContract.Contacts表以检索所有联系人
游标contactsUrsor=getContentResolver().query(contactsUri,
空,空,空,
Contacts contract.Contacts.DISPLAY_NAME+“ASC”);
如果(contactsUrsor.moveToFirst()){
做{
long contactId=contactsCursor.getLong(contactsCursor
.getColumnIndex(“_ID”);
Uri dataUri=ContactsContract.Data.CONTENT\u Uri;
//查询ContactsContract.Data表以检索单个项目,如
//每个联系人对应的家庭电话、手机等
游标dataCursor=getContentResolver().query(dataUri,
无效的
contacts contract.Data.CONTACT_ID+“=”+contactId,
空,空);
字符串displayName=“”;
字符串mobilePhone=“”;
if(dataCursor.moveToFirst()){
//获取显示名称
displayName=dataCursor
.getString(数据游标)
.getColumnIndex(contacts contract.Data.DISPLAY_NAME));
做{
//获取电话号码
如果(数据游标
.getString(
数据游标
.getColumnIndex(“mimetype”))
.equals(contacts.contract.commondatatypes.Phone.CONTENT\u ITEM\u TYPE)){
开关(dataCursor.getInt(dataCursor
.getColumnIndex(“数据2”)){
案例联系人contract.commondatatypes.Phone.TYPE\u手机:
移动电话=数据光标
.getString(数据游标)
.getColumnIndex(“数据1”);
打破
}
}
}while(dataCursor.moveToNext());
字符串详细信息=”;
//将各种信息连接到单个字符串
if(mobilePhone!=null&&!mobilePhone.equals(“”)
详细信息=手机+“\n”;
//向光标添加id、显示名称、照片路径和其他详细信息
mMatrixCursor.addRow(新对象[]){
Long.toString(contactId),displayName,details});
}
}while(contactsCursor.moveToNext());
}
返回mMatrixCursor;
}
@凌驾
受保护的void onPostExecute(游标结果){
//将包含联系人的光标设置为listview
swapCursor(结果);
Log.d(标记“onPostExecute:”+结果);
}
}

在EditText中添加文本后,还需要重置ListViewadapter

searchEditText.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                System.out.println("Text [" + s + "] - Start [" + start + "] - Before [" + before + "] - Count [" + count + "]");
                if (count < before) {
                    listAdapter.resetData(); // MARK: Resetting adapter here
                }
                listAdapter.getFilter().filter(s);
            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                                          int arg3) {
                // TODO Auto-generated method stub

            }

            @Override
            public void afterTextChanged(Editable arg0) {
                // TODO Auto-generated method stub
            }
        });
searchEditText.addTextChangedListener(新的TextWatcher(){
@凌驾
public void onTextChanged(字符序列、int start、int before、int count){
System.out.println(“文本[“+s+”]-Start[“+Start+”]-Before[“+Before+”]-Count[“+Count+”]);
如果(计数<之前){
listAdapter.resetData();//标记:在此处重置适配器
}
listAdapter.getFilter().filter;
}
@凌驾
更改前的公共void(字符序列arg0、int arg1、int arg2、,
int arg3){
//TODO自动生成的方法存根
}
@凌驾
public void PostTextChanged(可编辑arg0){
//TODO自动生成的方法存根
}
});

注意:resetData()是一种自定义方法,在该方法中,必须用应用过滤器后出现的新列表数据替换列表数据。然后最后通知适配器。

对不起,我对Android还比较陌生。你能解释一下如何根据我的例子重置数据吗?你需要查看下面提到的URL的教程。请浏览以下链接:尝试将更改通知适配器。使用mAdapter.notifyDatasetChanged();完成过滤后。如果您说logcat正在显示过滤列表,那么显示新列表时会出现问题。否。Logcat未显示筛选列表。它只显示键入的字符。请在mAdapter.getFilter.filter上使用断点,然后查看筛选列表的外观。。。你试过通知适配器了吗?@Denis95似乎我无法像这样过滤
SimpleCursorAdapter
。是的,我试过
notifyDatasetChanged()。什么也没发生。