How do I bind contact cursor data to a MultiAutoCompleteTextView with chips

I have been at this for almost two weeks now. I believe I have come close, but I can't quite get the final product to work. I have a functionality similar to email in my app. But instead of email addresses, it uses phone numbers. The gmail app on android is able to use a MultiAutoCompleteTextView with chips to display recipient email addresses. That is what I want to do. Through my research and trials, I am able to create the MultiAutoCompleteTextView, but without the chips. There are a number of questions and answers here on the same subject. But invariably, none of the ones I find has an example that binds the data from a user's contact book to the MultiAutoCompleteTextView. All the examples I see use their own made up simple arrays, as if the final step were trivial. But the final step is where I am stuck. Each time I try to bind the contact book to an MultiAutoCompleteTextView with chips, the code fails. So my question is quite extremely specific: How do I bind the contact book to an MultiAutoCompleteTextView with chips? For some context, I have already read Chips widget in Android application and bunch of other articles and responses besides. Is anyone aware of my specific use case? The gmail use case?

EDIT

Following is the code I use with https://github.com/splitwise/TokenAutoComplete . But the getView of my adapter is never called.

code to bind adapter to editText

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

code to load contact book

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

my adapter

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

}

my contact object: accessors and constructor not shown

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

My TokenCompleteTextView: ?? what goes inside 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);

}

}

Answers


Few weeks ago i was in your situation, and what I did was to use a library for the chips

I used this one

as for the bind with the contacts be more specific where are you stuck and what are you get ?


Need Your Help

QTcpSocket does not flush HTTP headers (Comet pattern)

javascript qt http comet qtcpsocket

Implementing a simple HTTP server in Qt, with the purpose of streaming real time data to an XMLHttpRequest object (AJAX/JavaScript).

Python: pynotify network problem

python pynotify

I am using pynotify and this is the code I am trying to get to work: