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

Posted

技术标签:

【中文标题】如何使用 EditText 在列表视图中搜索联系人?【英文标题】:How can I search Contacts in a List View using an EditText? 【发布时间】:2021-08-03 13:23:12 【问题描述】:

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

这是显示联系人的“AddContact”活动

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 类

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'类

  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;




【问题讨论】:

【参考方案1】:

您需要做的,只需在您的适配器类中创建一个方法,

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();

现在你必须在你的活动类中调用这个方法。

 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) 
        
    
);

【讨论】:

以上是关于如何使用 EditText 在列表视图中搜索联系人?的主要内容,如果未能解决你的问题,请参考以下文章

EditText - 如何检测输入 3 个或更多字符并执行搜索

Android listview edittext过滤空间按钮?

android - 搜索列表视图?

如何使用自定义列表视图在edittext过滤器中获取空间?可以使用简单的适配器吗?

使用Recyclerview的searchview EditText

如何在 Android for Android api 11+ 的列表视图中显示联系人