如何将联系人光标数据绑定到带有芯片的 MultiAutoCompleteTextView

Posted

技术标签:

【中文标题】如何将联系人光标数据绑定到带有芯片的 MultiAutoCompleteTextView【英文标题】:How do I bind contact cursor data to a MultiAutoCompleteTextView with chips 【发布时间】:2014-05-03 15:41:32 【问题描述】:

我已经在这工作了将近两个星期了。我相信我已经接近了,但我不能完全让最终产品工作。我的应用程序中有一个类似于电子邮件的功能。但它使用电话号码而不是电子邮件地址。 android 上的 gmail 应用程序能够使用 MultiAutoCompleteTextView withchips 来显示收件人电子邮件地址。这就是我想做的。通过我的研究和试验,我能够创建 MultiAutoCompleteTextView,但没有芯片。这里有许多关于同一主题的问题和答案。但总是,我发现没有一个示例将数据从用户通讯录绑定到 MultiAutoCompleteTextView。我看到的所有示例都使用它们自己组成的简单数组,好像最后一步很简单。但最后一步是我卡住的地方。每次我尝试将通讯录绑定到带有芯片的 MultiAutoCompleteTextView 时,代码都会失败。所以我的问题非常具体:如何将通讯录绑定到带有芯片的 MultiAutoCompleteTextView? 对于某些上下文,我已经阅读了Chips widget in Android application 以及其他一些文章和回复。有人知道我的具体用例吗? gmail 用例?

编辑

以下是我与 https://github.com/splitwise/TokenAutoComplete 一起使用的代码。但是我的适配器的getView 永远不会被调用。

将适配器绑定到editText的代码

mAdapter = new ContactAdapter(getActivity(), mPeopleList, R.layout.contacts_row);
multiEdit = (ContactsAutoCompleteView) view.findViewById(R.id.multi_edit);
multiEdit.setAdapter(mAdapter);

加载通讯录的代码

public void PopulatePeopleList() 

    mPeopleList.clear();

    Cursor people = getActivity().getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null,
            null);

    while (people.moveToNext()) 
        String contactName = people.getString(people.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

        String contactId = people.getString(people.getColumnIndex(ContactsContract.Contacts._ID));
        String hasPhone = people.getString(people.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));

        if (Integer.parseInt(hasPhone) > 0) 

            // You know have the number so now query it like this
            Cursor phones = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null);
            while (phones.moveToNext()) 

                // store numbers and display a dialog letting the user select which.
                String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                String numberType = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));

                if (numberType.equals("0")) 
                    numberType = "Work";
                 else if (numberType.equals("1")) 
                    numberType = "Home";
                 else if (numberType.equals("2")) 
                    numberType = "Mobile";
                 else 
                    numberType = "Other";
                
                mPeopleList.add(new Contact(contactName, phoneNumber, numberType));
            
            phones.close();
        
    
    people.close();

    getActivity().startManagingCursor(people);

我的适配器

public class ContactAdapter extends ArrayAdapter<Contact> 

    private final Context mContext;
    private final int mRowResourceId;
    private final LayoutInflater mInflater;
    ArrayList<Contact> mContacts;

    public ContactAdapter(Context context, ArrayList<Contact> contacts, int contactsRow) 
        super(context, contactsRow, contacts);
        mContext = context;
        mRowResourceId = contactsRow;
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mContacts = contacts;
    

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

        View rowView = convertView;
        if (null == rowView) 
            rowView = mInflater.inflate(mRowResourceId, parent, false);
            ViewHolder viewsHolder = new ViewHolder();
            viewsHolder.name = (TextView) rowView.findViewById(R.id.contact_name);
            viewsHolder.phone = (TextView) rowView.findViewById(R.id.contact_phone);
            viewsHolder.type = (TextView) rowView.findViewById(R.id.contact_type);
            rowView.setTag(viewsHolder);
        
        ViewHolder viewsHolder = (ViewHolder) rowView.getTag();
        Contact con = mContacts.get(position);// getItem(position);
        viewsHolder.name.setText(con.getName());
        viewsHolder.phone.setText(con.getPhone());
        viewsHolder.type.setText(con.getType());
        return rowView;
    

    static class ViewHolder 
        TextView name;
        TextView phone;
        TextView type;
    


我的联系人对象:未显示访问器和构造函数

public class Contact implements Serializable 
    private static final long serialVersionUID = 1L;
    private String name;
    private String phone;
    private String type;

我的 TokenCompleteTextView: ?? defaultObject 里面有什么

public class ContactsAutoCompleteView extends TokenCompleteTextView 

public ContactsAutoCompleteView(Context context, AttributeSet attrs) 
    super(context, attrs);


@Override
protected View getViewForObject(Object object) 
    Contact p = (Contact) object;

    LayoutInflater l = (LayoutInflater) getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    RelativeLayout view = (RelativeLayout) l.inflate(R.layout.contacts_row,
            (ViewGroup) ContactsAutoCompleteView.this.getParent(), false);
    ((TextView) view.findViewById(R.id.contact_name)).setText(p.getName());
    ((TextView) view.findViewById(R.id.contact_phone)).setText(p.getPhone());
    ((TextView) view.findViewById(R.id.contact_type)).setText(p.getType());

    return view;


@Override
protected Object defaultObject(String completionText) 
    //what goes here?


@Override
public void setSelected(boolean selected) 
    super.setSelected(selected);


【问题讨论】:

当我尝试使用芯片时,当我在 textview 中输入时没有任何反应,没有任何建议。然后我在调试模式下运行代码,发现适配器从来没有被访问过。 如果您的数据模型是游标,为什么不使用 SimpleCursorAdapter? @pskink 这是我在找到chip 库之前所拥有的。我展示的芯片库需要一个 Contact 对象而不是 `Map 我已经发布了一个类似的搜索姓名或电话号码的解决方案,那么添加电子邮件功能有什么难的呢? ***.com/questions/22443791/… @pskink 是的,我记得你一路上的帮助。但是chips 非常重要。 Gmail 使用这些芯片。问题是当我尝试包含代码失败的芯片时。 【参考方案1】:

几周前我遇到了你的情况,我所做的就是使用一个库来存放芯片

我用this one

至于与联系人的绑定,请更具体地说明您在哪里卡住了,您得到了什么?

【讨论】:

谢谢。我会看看你的链接。但正如我上面解释的,当我尝试使用芯片库时,我的适配器的getview 方法永远不会被调用。 其实我只是看了你的图书馆。我试过了。我将编辑我的答案以显示我的代码失败。但基本上我扩展了 ArrayAdapter 并将其传递给 textview。 我已编辑以显示我的完整代码。既然你已经解决了同样的问题,你可能是我的希望。谢谢。您可以使用适当的反馈/提示编辑您的回复。谢谢。 你对defaultObject的实现是什么?我知道我的 POJO 比示例代码中的更复杂。 我的 defaultObject 实现不支持并返回空联系人

以上是关于如何将联系人光标数据绑定到带有芯片的 MultiAutoCompleteTextView的主要内容,如果未能解决你的问题,请参考以下文章

获取带有全名详细信息和电话号码的 SINGLE 光标

如何在Vue js中绑定带有芯片的复选框(双向绑定)

带有光标适配器滚动问题的android列表视图

如何仅显示电话联系人(不包括 SIM 联系人)

带有联系人照片的联系人列表会产生性能问题

如何将光标中的值存储到android中的字符串中