如何使用 EditText 在列表视图中搜索联系人?

How can I search Contacts in a List View using an EditText?

我在 ListView 的 activity 电话簿中显示联系人。我想添加一个 EditText 来搜索联系人。我在 'search_contacts(CharSequence c)' 方法中尝试过 'addTextChangedListener' 但我想我实施错了。

这是'AddContact'activity显示联系人

public class AddContact extends AppCompatActivity {

//for Permission
public static final int PERMISSIONS_REQUEST_READ_CONTACTS = 1;
//EditText to search contacts and update listview
private EditText search_text;

private ContactAdapter dataAdapter;

//ListView will show Contact Name and his/her Phone Number
private ListView listView;
private List<ContactsInfo> contactsInfoList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_contact);
    listView = findViewById(R.id.contactslist);
    requestContactPermission();

    search_text = findViewById(R.id.searchedittext);
    search_text.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                search_contacts(s);
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            search_contacts(s);
        }

        @Override
        public void afterTextChanged(Editable s) {
            search_contacts(s);
        }
    });
}

private void search_contacts(CharSequence c) {
    dataAdapter.getFilter().filter(c.toString().toLowerCase());
    listView.setAdapter(dataAdapter);
}

//Checking if user has granted Reading Contact Permission
public void requestContactPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    android.Manifest.permission.READ_CONTACTS)) {
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("Read contacts access needed");
                builder.setPositiveButton(android.R.string.ok, null);
                builder.setMessage("Please enable access to contacts.");
                builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @TargetApi(Build.VERSION_CODES.M)
                    @Override
                    public void onDismiss(DialogInterface dialog) {
                        requestPermissions(
                                new String[]{android.Manifest.permission.READ_CONTACTS}
                                , PERMISSIONS_REQUEST_READ_CONTACTS);
                    }
                });
                builder.show();
            } else {
                ActivityCompat.requestPermissions(this,
                        new String[]{android.Manifest.permission.READ_CONTACTS},
                        PERMISSIONS_REQUEST_READ_CONTACTS);
            }
        } else {
            getContacts();
        }
    } else {
        getContacts();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case PERMISSIONS_REQUEST_READ_CONTACTS: {
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                getContacts();
            } else {
                Toast.makeText(this, "You have disabled a contacts permission", Toast.LENGTH_LONG).show();
            }
            return;
        }
    }
}

private void getContacts() {
    String contactId;
    String displayName;
    contactsInfoList = new ArrayList<>();
    Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
    if (cursor.getCount() > 0) {
        while (cursor.moveToNext()) {
            int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));
            if (hasPhoneNumber > 0) {

                ContactsInfo contactsInfo = new ContactsInfo();
                contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
                displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

                contactsInfo.setContactId(contactId);
                contactsInfo.setDisplayName(displayName);

                Cursor phoneCursor = getContentResolver().query(
                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        null,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
                        new String[]{contactId},
                        null);

                if (phoneCursor.moveToNext()) {
                    String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                    contactsInfo.setPhoneNumber(phoneNumber);
                }

                phoneCursor.close();
                contactsInfoList.add(contactsInfo);
            }
        }
    }
    cursor.close();

    dataAdapter = new ContactAdapter(AddContact.this, R.layout.rowadd, contactsInfoList);
    listView.setAdapter(dataAdapter);
}
}

这是 ContactAdapter class

public class ContactAdapter extends ArrayAdapter<ContactsInfo> {

private List<ContactsInfo> contactsInfoList;
private Context context;
private LayoutInflater mLayoutInflater;

public ContactAdapter(@NonNull Context context, int resource, @NonNull List<ContactsInfo> objects) {
    super(context, resource, objects);
    this.contactsInfoList = objects;
    this.context = context;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    ViewHolder holder;

    if (convertView == null) {
        LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = vi.inflate(R.layout.rowadd, null);

        holder = new ViewHolder();
        holder.displayName = (TextView) convertView.findViewById(R.id.name);
        holder.phoneNumber = (TextView) convertView.findViewById(R.id.number);
        holder.addContact = (ImageView) convertView.findViewById(R.id.add);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    ContactsInfo contactsInfo = contactsInfoList.get(position);
    holder.displayName.setText(contactsInfo.getDisplayName());
    holder.phoneNumber.setText(contactsInfo.getPhoneNumber());
    ViewHolder finalHolder = holder;
    return convertView;
}

private class ViewHolder {
    TextView displayName;
    TextView phoneNumber;
    ImageView addContact;
    }
}

最后一个是'ContactsInfo'class

  public class ContactsInfo {


private String contactId;
private String displayName;
private String phoneNumber;

public String getContactId() {
    return contactId;
}

public void setContactId(String contactId) {
    this.contactId = contactId;
}

public String getDisplayName() {
    return displayName;
}

public void setDisplayName(String displayName) {
    this.displayName = displayName;
}

public String getPhoneNumber() {
    return phoneNumber;
}

public void setPhoneNumber(String phoneNumber) {
    this.phoneNumber = phoneNumber;
}


}

您只需在适配器中创建一个方法即可 class,

List<ContactsInfo> contactsInfoList;
private List<ContactsInfo> contactInfoFiltered;

public ContactAdapter(@NonNull Context context, int resource, @NonNull List<ContactsInfo> objects) {
super(context, resource, objects);
this.contactsInfoList = objects;
this.context = context;
this.contactInfoFiltered= new ArrayList<>();
this.contactInfoFiltered.addAll(contactsInfoList);

}

public void searchContact(String charText) {
    charText = charText.toLowerCase(Locale.getDefault());
    contactsInfoList.clear();
    if (charText.length() == 0) {
        contactsInfoList.addAll(contactInfoFiltered);
    } else {
        for (ContactsInfo vp : contactInfoFiltered) {
           if(vp.getDisplayName().toLowerCase(Locale.getDefault()).contains(charText) || vp.getPhoneNumber().toLowerCase(Locale.getDefault()).contains(charText){
                contactsInfoList.add(vp);
            }
        }
    }
    notifyDataSetChanged();
}

现在您必须在 activity class 中调用此方法。

 search_text.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if(dataAdapter!=null){
         dataAdapter.searchContact(s.toString())
        }
    }

    @Override
    public void afterTextChanged(Editable s) {
        
    }
});