如何使用 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) {
}
});
我在 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) {
}
});