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