diff options
Diffstat (limited to 'java/com/android/dialer/contactsfragment/ContactsAdapter.java')
-rw-r--r-- | java/com/android/dialer/contactsfragment/ContactsAdapter.java | 102 |
1 files changed, 64 insertions, 38 deletions
diff --git a/java/com/android/dialer/contactsfragment/ContactsAdapter.java b/java/com/android/dialer/contactsfragment/ContactsAdapter.java index 4692eff5d..d8ee3d189 100644 --- a/java/com/android/dialer/contactsfragment/ContactsAdapter.java +++ b/java/com/android/dialer/contactsfragment/ContactsAdapter.java @@ -20,16 +20,29 @@ import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract.Contacts; +import android.support.annotation.IntDef; import android.support.v4.util.ArrayMap; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; +import android.view.View; import android.view.ViewGroup; -import android.widget.TextView; import com.android.contacts.common.ContactPhotoManager; +import com.android.contacts.common.lettertiles.LetterTileDrawable; import com.android.dialer.common.Assert; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** List adapter for the union of all contacts associated with every account on the device. */ -final class ContactsAdapter extends RecyclerView.Adapter<ContactViewHolder> { +final class ContactsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { + + private static final int UNKNOWN_VIEW_TYPE = 0; + private static final int ADD_CONTACT_VIEW_TYPE = 1; + private static final int CONTACT_VIEW_TYPE = 2; + + /** An Enum for the different row view types shown by this adapter. */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({UNKNOWN_VIEW_TYPE, ADD_CONTACT_VIEW_TYPE, CONTACT_VIEW_TYPE}) + @interface ContactsViewType {} private final ArrayMap<ContactViewHolder, Integer> holderMap = new ArrayMap<>(); private final Context context; @@ -41,7 +54,7 @@ final class ContactsAdapter extends RecyclerView.Adapter<ContactViewHolder> { // Number of contacts that correspond to each header in {@code headers}. private final int[] counts; - public ContactsAdapter(Context context, Cursor cursor) { + ContactsAdapter(Context context, Cursor cursor) { this.context = context; this.cursor = cursor; headers = cursor.getExtras().getStringArray(Contacts.EXTRA_ADDRESS_BOOK_INDEX_TITLES); @@ -49,15 +62,31 @@ final class ContactsAdapter extends RecyclerView.Adapter<ContactViewHolder> { } @Override - public ContactViewHolder onCreateViewHolder(ViewGroup parent, int position) { - return new ContactViewHolder( - LayoutInflater.from(context).inflate(R.layout.contact_row, parent, false)); + public RecyclerView.ViewHolder onCreateViewHolder( + ViewGroup parent, @ContactsViewType int viewType) { + switch (viewType) { + case ADD_CONTACT_VIEW_TYPE: + return new AddContactViewHolder( + LayoutInflater.from(context).inflate(R.layout.add_contact_row, parent, false)); + case CONTACT_VIEW_TYPE: + return new ContactViewHolder( + LayoutInflater.from(context).inflate(R.layout.contact_row, parent, false)); + case UNKNOWN_VIEW_TYPE: + default: + throw Assert.createIllegalStateFailException("Invalid view type: " + viewType); + } } @Override - public void onBindViewHolder(ContactViewHolder contactViewHolder, int position) { + public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { + if (viewHolder instanceof AddContactViewHolder) { + return; + } + + ContactViewHolder contactViewHolder = (ContactViewHolder) viewHolder; holderMap.put(contactViewHolder, position); - cursor.moveToPosition(position); + // Cursor should be offset by 1 because of add contact row + cursor.moveToPosition(position - 1); String name = getDisplayName(cursor); String header = getHeaderString(position); @@ -70,7 +99,7 @@ final class ContactsAdapter extends RecyclerView.Adapter<ContactViewHolder> { getPhotoId(cursor), getPhotoUri(cursor), name, - 0); + LetterTileDrawable.TYPE_DEFAULT); String photoDescription = context.getString(com.android.contacts.common.R.string.description_quick_contact_for, name); @@ -79,44 +108,36 @@ final class ContactsAdapter extends RecyclerView.Adapter<ContactViewHolder> { // Always show the view holder's header if it's the first item in the list. Otherwise, compare // it to the previous element and only show the anchored header if the row elements fall into // the same sublists. - if (position == 0) { - contactViewHolder.bind(header, name, contactUri, true); - } else { - boolean showHeader = !header.equals(getHeaderString(position - 1)); - contactViewHolder.bind(header, name, contactUri, showHeader); + boolean showHeader = position == 0 || !header.equals(getHeaderString(position - 1)); + contactViewHolder.bind(header, name, contactUri, showHeader); + } + + @Override + public @ContactsViewType int getItemViewType(int position) { + return position == 0 ? ADD_CONTACT_VIEW_TYPE : CONTACT_VIEW_TYPE; + } + + @Override + public void onViewRecycled(RecyclerView.ViewHolder contactViewHolder) { + super.onViewRecycled(contactViewHolder); + if (contactViewHolder instanceof ContactViewHolder) { + holderMap.remove(contactViewHolder); } } public void refreshHeaders() { for (ContactViewHolder holder : holderMap.keySet()) { - onBindViewHolder(holder, holderMap.get(holder)); + int position = holderMap.get(holder); + boolean showHeader = + position == 0 || !getHeaderString(position).equals(getHeaderString(position - 1)); + int visibility = showHeader ? View.VISIBLE : View.INVISIBLE; + holder.getHeaderView().setVisibility(visibility); } } @Override public int getItemCount() { - return cursor == null ? 0 : cursor.getCount(); - } - - public String getHeader(int position) { - return getHolderAt(position).getHeader(); - } - - public TextView getHeaderView(int position) { - return getHolderAt(position).getHeaderView(); - } - - public void setHeaderVisibility(int position, int visibility) { - getHolderAt(position).getHeaderView().setVisibility(visibility); - } - - private ContactViewHolder getHolderAt(int position) { - for (ContactViewHolder holder : holderMap.keySet()) { - if (holderMap.get(holder) == position) { - return holder; - } - } - throw Assert.createIllegalStateFailException("No holder for position: " + position); + return (cursor == null ? 0 : cursor.getCount()) + 1; // add contact } private static String getDisplayName(Cursor cursor) { @@ -138,7 +159,12 @@ final class ContactsAdapter extends RecyclerView.Adapter<ContactViewHolder> { return Contacts.getLookupUri(contactId, lookupKey); } - private String getHeaderString(int position) { + public String getHeaderString(int position) { + if (position == 0) { + return "+"; + } + position--; + int index = -1; int sum = 0; while (sum <= position) { |