Getting rid of contact list item view cache.

Also, separating multipicker views from regular views.

Change-Id: I3b7639eb641d1d87e30ef810492a5c43a662a50b
diff --git a/src/com/android/contacts/ContactNameHighlightingAnimation.java b/src/com/android/contacts/ContactNameHighlightingAnimation.java
index 3a17bb6..68664b3 100644
--- a/src/com/android/contacts/ContactNameHighlightingAnimation.java
+++ b/src/com/android/contacts/ContactNameHighlightingAnimation.java
@@ -15,6 +15,7 @@
  */
 package com.android.contacts;
 
+import com.android.contacts.list.ContactListItemView;
 import com.android.contacts.widget.TextHighlightingAnimation;
 
 import android.view.View;
diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
index 0fb03e5..3187e41 100644
--- a/src/com/android/contacts/ContactsListActivity.java
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -2354,16 +2354,4 @@
             mListState = null;
         }
     }
-
-    public final static class ContactListItemCache {
-        public CharArrayBuffer nameBuffer = new CharArrayBuffer(128);
-        public CharArrayBuffer dataBuffer = new CharArrayBuffer(128);
-        public CharArrayBuffer highlightedTextBuffer = new CharArrayBuffer(128);
-        public TextWithHighlighting textWithHighlighting;
-        public CharArrayBuffer phoneticNameBuffer = new CharArrayBuffer(128);
-        public long phoneId;
-        // phoneNumber only validates when phoneId = INVALID_PHONE_ID
-        public String phoneNumber;
-    }
-
 }
diff --git a/src/com/android/contacts/MultiplePhonePickerActivity.java b/src/com/android/contacts/MultiplePhonePickerActivity.java
index 502e8f1..3eeb20a 100644
--- a/src/com/android/contacts/MultiplePhonePickerActivity.java
+++ b/src/com/android/contacts/MultiplePhonePickerActivity.java
@@ -19,6 +19,7 @@
 import com.android.contacts.list.MultiplePhoneExtraAdapter;
 import com.android.contacts.list.MultiplePhonePickerAdapter;
 import com.android.contacts.list.MultiplePhonePickerConfiguration;
+import com.android.contacts.list.MultiplePhonePickerItemView;
 import com.android.contacts.list.MultiplePhoneSelection;
 
 import android.app.ProgressDialog;
@@ -109,11 +110,12 @@
 
     public OnClickListener mCheckBoxClickerListener = new OnClickListener () {
         public void onClick(View v) {
-            final ContactListItemCache cache = (ContactListItemCache) v.getTag();
-            if (cache.phoneId != MultiplePhoneExtraAdapter.INVALID_PHONE_ID) {
-                mUserSelection.setPhoneSelected(cache.phoneId, ((CheckBox) v).isChecked());
+            final MultiplePhonePickerItemView itemView =
+                    (MultiplePhonePickerItemView) v.getParent();
+            if (itemView.phoneId != MultiplePhoneExtraAdapter.INVALID_PHONE_ID) {
+                mUserSelection.setPhoneSelected(itemView.phoneId, ((CheckBox) v).isChecked());
             } else {
-                mUserSelection.setPhoneSelected(cache.phoneNumber,
+                mUserSelection.setPhoneSelected(itemView.phoneNumber,
                         ((CheckBox) v).isChecked());
             }
             updateWidgets(true);
diff --git a/src/com/android/contacts/list/ContactItemListAdapter.java b/src/com/android/contacts/list/ContactItemListAdapter.java
index 4fc8142..9168ac6 100644
--- a/src/com/android/contacts/list/ContactItemListAdapter.java
+++ b/src/com/android/contacts/list/ContactItemListAdapter.java
@@ -15,12 +15,10 @@
  */
 package com.android.contacts.list;
 
-import com.android.contacts.ContactListItemView;
 import com.android.contacts.ContactPresenceIconUtil;
 import com.android.contacts.ContactsListActivity;
 import com.android.contacts.ContactsSectionIndexer;
 import com.android.contacts.R;
-import com.android.contacts.ContactsListActivity.ContactListItemCache;
 import com.android.contacts.widget.TextWithHighlighting;
 
 import android.content.Context;
@@ -253,14 +251,12 @@
     public View newView(Context context, Cursor cursor, ViewGroup parent) {
         final ContactListItemView view = new ContactListItemView(context, null);
         view.setOnCallButtonClickListener(contactsListActivity);
-        view.setTag(new ContactsListActivity.ContactListItemCache());
         return view;
     }
 
     @Override
     public void bindView(View itemView, Context context, Cursor cursor) {
         final ContactListItemView view = (ContactListItemView)itemView;
-        final ContactListItemCache cache = (ContactListItemCache) view.getTag();
 
         int typeColumnIndex;
         int dataColumnIndex;
@@ -316,18 +312,18 @@
         }
 
         // Set the name
-        cursor.copyStringToBuffer(nameColumnIndex, cache.nameBuffer);
+        cursor.copyStringToBuffer(nameColumnIndex, view.nameBuffer);
         TextView nameView = view.getNameTextView();
-        int size = cache.nameBuffer.sizeCopied;
+        int size = view.nameBuffer.sizeCopied;
         if (size != 0) {
             if (highlightingEnabled) {
-                if (cache.textWithHighlighting == null) {
-                    cache.textWithHighlighting = createTextWithHighlighting();
+                if (view.textWithHighlighting == null) {
+                    view.textWithHighlighting = createTextWithHighlighting();
                 }
-                buildDisplayNameWithHighlighting(nameView, cursor, cache.nameBuffer,
-                        cache.highlightedTextBuffer, cache.textWithHighlighting);
+                buildDisplayNameWithHighlighting(nameView, cursor, view.nameBuffer,
+                        view.highlightedTextBuffer, view.textWithHighlighting);
             } else {
-                nameView.setText(cache.nameBuffer.data, 0, size);
+                nameView.setText(view.nameBuffer.data, 0, size);
             }
         } else {
             nameView.setText(mUnknownNameText);
@@ -435,10 +431,10 @@
             if (phoneticNameColumnIndex != -1) {
 
                 // Set the name
-                cursor.copyStringToBuffer(phoneticNameColumnIndex, cache.phoneticNameBuffer);
-                int phoneticNameSize = cache.phoneticNameBuffer.sizeCopied;
+                cursor.copyStringToBuffer(phoneticNameColumnIndex, view.phoneticNameBuffer);
+                int phoneticNameSize = view.phoneticNameBuffer.sizeCopied;
                 if (phoneticNameSize != 0) {
-                    view.setLabel(cache.phoneticNameBuffer.data, phoneticNameSize);
+                    view.setLabel(view.phoneticNameBuffer.data, phoneticNameSize);
                 } else {
                     view.setLabel(null);
                 }
@@ -449,10 +445,10 @@
         }
 
         // Set the data.
-        cursor.copyStringToBuffer(dataColumnIndex, cache.dataBuffer);
+        cursor.copyStringToBuffer(dataColumnIndex, view.dataBuffer);
 
-        size = cache.dataBuffer.sizeCopied;
-        view.setData(cache.dataBuffer.data, size);
+        size = view.dataBuffer.sizeCopied;
+        view.setData(view.dataBuffer.data, size);
 
         // Set the label.
         if (!cursor.isNull(typeColumnIndex)) {
@@ -497,7 +493,6 @@
 
     protected void bindSectionHeader(View itemView, int position, boolean displaySectionHeaders) {
         final ContactListItemView view = (ContactListItemView)itemView;
-        final ContactListItemCache cache = (ContactListItemCache) view.getTag();
         if (!displaySectionHeaders) {
             view.setSectionHeader(null);
             view.setDividerVisible(true);
diff --git a/src/com/android/contacts/ContactListItemView.java b/src/com/android/contacts/list/ContactListItemView.java
similarity index 89%
rename from src/com/android/contacts/ContactListItemView.java
rename to src/com/android/contacts/list/ContactListItemView.java
index 9be3fba..4db52fa 100644
--- a/src/com/android/contacts/ContactListItemView.java
+++ b/src/com/android/contacts/list/ContactListItemView.java
@@ -14,13 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.contacts;
+package com.android.contacts.list;
 
-import com.android.contacts.ui.widget.DontPressWithParentImageView;
+import com.android.contacts.R;
+import com.android.contacts.widget.TextWithHighlighting;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
+import android.database.CharArrayBuffer;
 import android.graphics.Canvas;
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
@@ -45,7 +47,7 @@
     private static final int QUICK_CONTACT_BADGE_STYLE =
             com.android.internal.R.attr.quickContactBadgeStyleWindowMedium;
 
-    private final Context mContext;
+    protected final Context mContext;
 
     private final int mPreferredHeight;
     private final int mVerticalDividerMargin;
@@ -80,22 +82,41 @@
     private TextView mDataView;
     private TextView mSnippetView;
     private ImageView mPresenceIcon;
-    // Used to indicate the sequence of phones belong to the same contact in multi-picker
-    private View mChipView;
-    // Used to select the phone in multi-picker
-    private CheckBox mCheckBox;
 
     private int mPhotoViewWidth;
     private int mPhotoViewHeight;
     private int mLine1Height;
     private int mLine2Height;
     private int mLine3Height;
-    private int mChipWidth;
-    private int mChipRightMargin;
-    private int mCheckBoxMargin;
 
     private OnClickListener mCallButtonClickListener;
-    private OnClickListener mCheckBoxClickListener;
+
+    public CharArrayBuffer nameBuffer = new CharArrayBuffer(128);
+    public CharArrayBuffer dataBuffer = new CharArrayBuffer(128);
+    public CharArrayBuffer highlightedTextBuffer = new CharArrayBuffer(128);
+    public TextWithHighlighting textWithHighlighting;
+    public CharArrayBuffer phoneticNameBuffer = new CharArrayBuffer(128);
+
+    /**
+     * Special class to allow the parent to be pressed without being pressed itself.
+     * This way the line of a tab can be pressed, but the image itself is not.
+     */
+    // TODO: understand this
+    private static class DontPressWithParentImageView extends ImageView {
+
+        public DontPressWithParentImageView(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        @Override
+        public void setPressed(boolean pressed) {
+            // If the parent is pressed, do not set to pressed.
+            if (pressed && ((View) getParent()).isPressed()) {
+                return;
+            }
+            super.setPressed(pressed);
+        }
+    }
 
     public ContactListItemView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -128,12 +149,6 @@
                 resources.getDimensionPixelOffset(R.dimen.list_item_presence_icon_margin);
         mHeaderTextWidth =
                 resources.getDimensionPixelOffset(R.dimen.list_item_header_text_width);
-        mChipWidth =
-                resources.getDimensionPixelOffset(R.dimen.list_item_header_chip_width);
-        mChipRightMargin =
-                resources.getDimensionPixelOffset(R.dimen.list_item_header_chip_right_margin);
-        mCheckBoxMargin =
-                resources.getDimensionPixelOffset(R.dimen.list_item_header_checkbox_margin);
     }
 
     /**
@@ -143,10 +158,6 @@
         mCallButtonClickListener = callButtonClickListener;
     }
 
-    public void setOnCheckBoxClickListener(OnClickListener checkBoxClickListener) {
-        mCheckBoxClickListener = checkBoxClickListener;
-    }
-
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         // We will match parent's width and wrap content vertically, but make sure
@@ -187,14 +198,6 @@
             mPresenceIcon.measure(0, 0);
         }
 
-        if (isVisible(mChipView)) {
-            mChipView.measure(0, 0);
-        }
-
-        if (isVisible(mCheckBox)) {
-            mCheckBox.measure(0, 0);
-        }
-
         ensurePhotoViewSize();
 
         height = Math.max(height, mPhotoViewHeight);
@@ -234,66 +237,9 @@
         // by laying out the left and right sides. Then we will allocate the remainder
         // to the text fields in the middle.
 
-        // Left side
-        int leftBound = mPaddingLeft;
-        if (mChipView != null) {
-            mChipView.layout(leftBound, topBound, leftBound + mChipWidth, height);
-            leftBound += mChipWidth + mChipRightMargin;
-        }
-        View photoView = mQuickContact != null ? mQuickContact : mPhotoView;
-        if (photoView != null) {
-            // Center the photo vertically
-            int photoTop = topBound + (height - topBound - mPhotoViewHeight) / 2;
-            photoView.layout(
-                    leftBound,
-                    photoTop,
-                    leftBound + mPhotoViewWidth,
-                    photoTop + mPhotoViewHeight);
-            leftBound += mPhotoViewWidth + mGapBetweenImageAndText;
-        }
+        int leftBound = layoutLeftSide(height, topBound, mPaddingLeft);
+        int rightBound = layoutRightSide(height, topBound, right);
 
-        // Right side
-        int rightBound = right;
-        if (isVisible(mCallButton)) {
-            int buttonWidth = mCallButton.getMeasuredWidth();
-            rightBound -= buttonWidth;
-            mCallButton.layout(
-                    rightBound,
-                    topBound,
-                    rightBound + buttonWidth,
-                    height);
-            mVerticalDividerVisible = true;
-            ensureVerticalDivider();
-            rightBound -= mVerticalDividerWidth;
-            mVerticalDividerDrawable.setBounds(
-                    rightBound,
-                    topBound + mVerticalDividerMargin,
-                    rightBound + mVerticalDividerWidth,
-                    height - mVerticalDividerMargin);
-        } else {
-            mVerticalDividerVisible = false;
-        }
-
-        if (isVisible(mPresenceIcon)) {
-            int iconWidth = mPresenceIcon.getMeasuredWidth();
-            rightBound -= mPresenceIconMargin + iconWidth;
-            mPresenceIcon.layout(
-                    rightBound,
-                    topBound,
-                    rightBound + iconWidth,
-                    height);
-        }
-        if (isVisible(mCheckBox)) {
-            int checkBoxWidth = mCheckBox.getMeasuredWidth();
-            int checkBoxHight = mCheckBox.getMeasuredHeight();
-            rightBound -= mCheckBoxMargin + checkBoxWidth;
-            int checkBoxTop = topBound + (height - topBound - checkBoxHight) / 2;
-            mCheckBox.layout(
-                    rightBound,
-                    checkBoxTop,
-                    rightBound + checkBoxWidth,
-                    checkBoxTop + checkBoxHight);
-        }
         if (mHorizontalDividerVisible) {
             ensureHorizontalDivider();
             mHorizontalDividerDrawable.setBounds(
@@ -343,7 +289,65 @@
         }
     }
 
-    private boolean isVisible(View view) {
+    /**
+     * Performs layout of the left side of the view
+     *
+     * @return new left boundary
+     */
+    protected int layoutLeftSide(int height, int topBound, int leftBound) {
+        View photoView = mQuickContact != null ? mQuickContact : mPhotoView;
+        if (photoView != null) {
+            // Center the photo vertically
+            int photoTop = topBound + (height - topBound - mPhotoViewHeight) / 2;
+            photoView.layout(
+                    leftBound,
+                    photoTop,
+                    leftBound + mPhotoViewWidth,
+                    photoTop + mPhotoViewHeight);
+            leftBound += mPhotoViewWidth + mGapBetweenImageAndText;
+        }
+        return leftBound;
+    }
+
+    /**
+     * Performs layout of the right side of the view
+     *
+     * @return new right boundary
+     */
+    protected int layoutRightSide(int height, int topBound, int rightBound) {
+        if (isVisible(mCallButton)) {
+            int buttonWidth = mCallButton.getMeasuredWidth();
+            rightBound -= buttonWidth;
+            mCallButton.layout(
+                    rightBound,
+                    topBound,
+                    rightBound + buttonWidth,
+                    height);
+            mVerticalDividerVisible = true;
+            ensureVerticalDivider();
+            rightBound -= mVerticalDividerWidth;
+            mVerticalDividerDrawable.setBounds(
+                    rightBound,
+                    topBound + mVerticalDividerMargin,
+                    rightBound + mVerticalDividerWidth,
+                    height - mVerticalDividerMargin);
+        } else {
+            mVerticalDividerVisible = false;
+        }
+
+        if (isVisible(mPresenceIcon)) {
+            int iconWidth = mPresenceIcon.getMeasuredWidth();
+            rightBound -= mPresenceIconMargin + iconWidth;
+            mPresenceIcon.layout(
+                    rightBound,
+                    topBound,
+                    rightBound + iconWidth,
+                    height);
+        }
+        return rightBound;
+    }
+
+    protected boolean isVisible(View view) {
         return view != null && view.getVisibility() == View.VISIBLE;
     }
 
@@ -634,29 +638,6 @@
     }
 
     /**
-     * Returns the chip view for the multipicker, creating it if necessary.
-     */
-    public View getChipView() {
-        if (mChipView == null) {
-            mChipView = new View(mContext);
-            addView(mChipView);
-        }
-        return mChipView;
-    }
-
-    /**
-     * Returns the CheckBox view for the multipicker, creating it if necessary.
-     */
-    public CheckBox getCheckBoxView() {
-        if (mCheckBox == null) {
-            mCheckBox = new CheckBox(mContext);
-            mCheckBox.setOnClickListener(mCheckBoxClickListener);
-            addView(mCheckBox);
-        }
-        return mCheckBox;
-    }
-
-    /**
      * Adds or updates the presence icon view.
      */
     public void setPresence(Drawable icon) {
diff --git a/src/com/android/contacts/list/MultiplePhoneExtraAdapter.java b/src/com/android/contacts/list/MultiplePhoneExtraAdapter.java
index 09fc0db..66548db 100644
--- a/src/com/android/contacts/list/MultiplePhoneExtraAdapter.java
+++ b/src/com/android/contacts/list/MultiplePhoneExtraAdapter.java
@@ -15,10 +15,8 @@
  */
 package com.android.contacts.list;
 
-import com.android.contacts.ContactListItemView;
 import com.android.contacts.MultiplePhonePickerActivity;
 import com.android.contacts.R;
-import com.android.contacts.ContactsListActivity.ContactListItemCache;
 
 import android.content.Context;
 import android.text.TextUtils;
@@ -129,8 +127,7 @@
         // PhoneNumbers start from position of startPos + 1
         if (position >= startPos + 1 && position < startPos + viewCount) {
             View view;
-            if (convertView != null && convertView.getTag() != null &&
-                    convertView.getTag() instanceof ContactListItemCache) {
+            if (convertView != null) {
                 view = convertView;
             } else {
                 view = this.mMultiplePhonePickerActivity.mAdapter.newView(mContext, null, parent);
@@ -150,21 +147,19 @@
     }
 
     private void bindView(View view, final String label) {
-        ContactListItemView itemView = (ContactListItemView) view;
+        MultiplePhonePickerItemView itemView = (MultiplePhonePickerItemView) view;
         itemView.setDividerVisible(true);
         itemView.setSectionHeader(null);
         itemView.setLabel(null);
         itemView.setData(null, 0);
         itemView.removePhotoView();
 
-        final ContactListItemCache cache = (ContactListItemCache) view.getTag();
         itemView.getNameTextView().setText(label);
         CheckBox checkBox = itemView.getCheckBoxView();
         checkBox.setChecked(mSelection.isSelected(label));
         itemView.getChipView().setBackgroundResource(0);
-        cache.phoneId = INVALID_PHONE_ID;
-        cache.phoneNumber = label;
-        checkBox.setTag(cache);
+        itemView.phoneId = INVALID_PHONE_ID;
+        itemView.phoneNumber = label;
     }
 
     public void doFilter(final String constraint, boolean selectedOnly) {
diff --git a/src/com/android/contacts/list/MultiplePhonePickerAdapter.java b/src/com/android/contacts/list/MultiplePhonePickerAdapter.java
index e5dd609..393b35a 100644
--- a/src/com/android/contacts/list/MultiplePhonePickerAdapter.java
+++ b/src/com/android/contacts/list/MultiplePhonePickerAdapter.java
@@ -15,10 +15,8 @@
  */
 package com.android.contacts.list;
 
-import com.android.contacts.ContactListItemView;
 import com.android.contacts.ContactsListActivity;
 import com.android.contacts.MultiplePhonePickerActivity;
-import com.android.contacts.ContactsListActivity.ContactListItemCache;
 
 import android.content.Context;
 import android.database.Cursor;
@@ -73,17 +71,15 @@
 
     @Override
     public View newView(Context context, Cursor cursor, ViewGroup parent) {
-        final ContactListItemView view = new ContactListItemView(context, null);
+        final MultiplePhonePickerItemView view = new MultiplePhonePickerItemView(context, null);
         view.setOnCallButtonClickListener(mMultiplePhonePickerActivity);
         view.setOnCheckBoxClickListener(mMultiplePhonePickerActivity.mCheckBoxClickerListener);
-        view.setTag(new MultiplePhonePickerActivity.ContactListItemCache());
         return view;
     }
 
     @Override
     public void bindView(View itemView, Context context, Cursor cursor) {
-        final ContactListItemView view = (ContactListItemView)itemView;
-        final ContactListItemCache cache = (ContactListItemCache)view.getTag();
+        final MultiplePhonePickerItemView view = (MultiplePhonePickerItemView)itemView;
 
         int typeColumnIndex;
         int dataColumnIndex;
@@ -101,21 +97,19 @@
         defaultType = Phone.TYPE_HOME;
         photoColumnIndex = ContactsListActivity.PHONE_PHOTO_ID_COLUMN_INDEX;
 
-        cache.phoneId = Long.valueOf(cursor.getLong(ContactsListActivity.PHONE_ID_COLUMN_INDEX));
+        view.phoneId = Long.valueOf(cursor.getLong(ContactsListActivity.PHONE_ID_COLUMN_INDEX));
         CheckBox checkBox = view.getCheckBoxView();
-        checkBox.setChecked(mMultiplePhonePickerActivity.mUserSelection
-                .isSelected(cache.phoneId));
-        checkBox.setTag(cache);
+        checkBox.setChecked(mMultiplePhonePickerActivity.mUserSelection.isSelected(view.phoneId));
         int color = mMultiplePhonePickerActivity.getChipColor(cursor
                 .getLong(ContactsListActivity.PHONE_CONTACT_ID_COLUMN_INDEX));
         view.getChipView().setBackgroundResource(color);
 
         // Set the name
-        cursor.copyStringToBuffer(nameColumnIndex, cache.nameBuffer);
+        cursor.copyStringToBuffer(nameColumnIndex, view.nameBuffer);
         TextView nameView = view.getNameTextView();
-        int size = cache.nameBuffer.sizeCopied;
+        int size = view.nameBuffer.sizeCopied;
         if (size != 0) {
-            nameView.setText(cache.nameBuffer.data, 0, size);
+            nameView.setText(view.nameBuffer.data, 0, size);
         } else {
             nameView.setText(mUnknownNameText);
         }
@@ -150,10 +144,10 @@
             if (phoneticNameColumnIndex != -1) {
 
                 // Set the name
-                cursor.copyStringToBuffer(phoneticNameColumnIndex, cache.phoneticNameBuffer);
-                int phoneticNameSize = cache.phoneticNameBuffer.sizeCopied;
+                cursor.copyStringToBuffer(phoneticNameColumnIndex, view.phoneticNameBuffer);
+                int phoneticNameSize = view.phoneticNameBuffer.sizeCopied;
                 if (phoneticNameSize != 0) {
-                    view.setLabel(cache.phoneticNameBuffer.data, phoneticNameSize);
+                    view.setLabel(view.phoneticNameBuffer.data, phoneticNameSize);
                 } else {
                     view.setLabel(null);
                 }
@@ -164,10 +158,10 @@
         }
 
         // Set the data.
-        cursor.copyStringToBuffer(dataColumnIndex, cache.dataBuffer);
+        cursor.copyStringToBuffer(dataColumnIndex, view.dataBuffer);
 
-        size = cache.dataBuffer.sizeCopied;
-        view.setData(cache.dataBuffer.data, size);
+        size = view.dataBuffer.sizeCopied;
+        view.setData(view.dataBuffer.data, size);
 
         // Set the label.
         if (!cursor.isNull(typeColumnIndex)) {
diff --git a/src/com/android/contacts/list/MultiplePhonePickerItemView.java b/src/com/android/contacts/list/MultiplePhonePickerItemView.java
new file mode 100644
index 0000000..af4c6c8
--- /dev/null
+++ b/src/com/android/contacts/list/MultiplePhonePickerItemView.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.contacts.list;
+
+import com.android.contacts.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.CheckBox;
+
+/**
+ * A custom view for an item in the phone multi-picker list.
+ */
+public class MultiplePhonePickerItemView extends ContactListItemView {
+
+    // Used to indicate the sequence of phones belong to the same contact in multi-picker
+    private View mChipView;
+    // Used to select the phone in multi-picker
+    private CheckBox mCheckBox;
+
+    private int mChipWidth;
+    private int mChipRightMargin;
+    private int mCheckBoxMargin;
+
+    private OnClickListener mCheckBoxClickListener;
+
+    public long phoneId;
+    // phoneNumber only validates when phoneId = INVALID_PHONE_ID
+    public String phoneNumber;
+
+    public MultiplePhonePickerItemView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        Resources resources = context.getResources();
+        mChipWidth =
+                resources.getDimensionPixelOffset(R.dimen.list_item_header_chip_width);
+        mChipRightMargin =
+                resources.getDimensionPixelOffset(R.dimen.list_item_header_chip_right_margin);
+        mCheckBoxMargin =
+                resources.getDimensionPixelOffset(R.dimen.list_item_header_checkbox_margin);
+    }
+
+    public void setOnCheckBoxClickListener(OnClickListener checkBoxClickListener) {
+        mCheckBoxClickListener = checkBoxClickListener;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        if (isVisible(mChipView)) {
+            mChipView.measure(0, 0);
+        }
+
+        if (isVisible(mCheckBox)) {
+            mCheckBox.measure(0, 0);
+        }
+
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    }
+
+    @Override
+    protected int layoutLeftSide(int height, int topBound, int leftBound) {
+        if (mChipView != null) {
+            mChipView.layout(leftBound, topBound, leftBound + mChipWidth, height);
+            leftBound += mChipWidth + mChipRightMargin;
+        }
+
+        return super.layoutLeftSide(height, topBound, leftBound);
+    }
+
+    @Override
+    protected int layoutRightSide(int height, int topBound, int rightBound) {
+        rightBound = super.layoutRightSide(height, topBound, rightBound);
+
+        if (isVisible(mCheckBox)) {
+            int checkBoxWidth = mCheckBox.getMeasuredWidth();
+            int checkBoxHight = mCheckBox.getMeasuredHeight();
+            rightBound -= mCheckBoxMargin + checkBoxWidth;
+            int checkBoxTop = topBound + (height - topBound - checkBoxHight) / 2;
+            mCheckBox.layout(
+                    rightBound,
+                    checkBoxTop,
+                    rightBound + checkBoxWidth,
+                    checkBoxTop + checkBoxHight);
+        }
+
+        return rightBound;
+    }
+
+    /**
+     * Returns the chip view for the multipicker, creating it if necessary.
+     */
+    public View getChipView() {
+        if (mChipView == null) {
+            mChipView = new View(mContext);
+            addView(mChipView);
+        }
+        return mChipView;
+    }
+
+    /**
+     * Returns the CheckBox view for the multipicker, creating it if necessary.
+     */
+    public CheckBox getCheckBoxView() {
+        if (mCheckBox == null) {
+            mCheckBox = new CheckBox(mContext);
+            mCheckBox.setOnClickListener(mCheckBoxClickListener);
+            addView(mCheckBox);
+        }
+        return mCheckBox;
+    }
+}
diff --git a/src/com/android/contacts/ui/widget/DontPressWithParentImageView.java b/src/com/android/contacts/ui/widget/DontPressWithParentImageView.java
deleted file mode 100644
index bdb0e0a..0000000
--- a/src/com/android/contacts/ui/widget/DontPressWithParentImageView.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.ui.widget;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.ImageView;
-
-/**
- * Special class to to allow the parent to be pressed without being pressed itself.
- * This way the line of a tab can be pressed, but the image itself is not.
- */
-public class DontPressWithParentImageView extends ImageView {
-
-    public DontPressWithParentImageView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    public void setPressed(boolean pressed) {
-        // If the parent is pressed, do not set to pressed.
-        if (pressed && ((View) getParent()).isPressed()) {
-            return;
-        }
-        super.setPressed(pressed);
-    }
-}