Show label more appropriately.

- align bottom of data and label
- refrain overlap between data and label
- make label's ellipsys effective

Bug: 5438757
Change-Id: I94de518e53688a7bdf889c3ec0f8e3efa57670d5
diff --git a/res/layout/contact_tile_frequent_phone.xml b/res/layout/contact_tile_frequent_phone.xml
index 5bd82cd..d3f64e4 100644
--- a/res/layout/contact_tile_frequent_phone.xml
+++ b/res/layout/contact_tile_frequent_phone.xml
@@ -57,8 +57,8 @@
 
         <LinearLayout
             android:orientation="horizontal"
-            android:layout_height="wrap_content"
             android:layout_width="match_parent"
+            android:layout_height="wrap_content"
             android:layout_below="@id/contact_tile_name"
             android:layout_toRightOf="@id/image_container"
             android:gravity="center_vertical">
@@ -71,7 +71,8 @@
                 android:textSize="14sp"
                 android:textColor="@color/dialtacts_secondary_text_color"
                 android:layout_marginLeft="8dip"
-                android:singleLine="true"/>
+                android:singleLine="true"
+                android:layout_gravity="bottom" />
 
             <TextView
                 android:id="@+id/contact_tile_phone_type"
@@ -84,7 +85,8 @@
                 android:textAllCaps="true"
                 android:textColor="@color/dialtacts_secondary_text_color"
                 android:layout_marginLeft="8dip"
-                android:gravity="right" />
+                android:gravity="right"
+                android:layout_gravity="bottom" />
 
         </LinearLayout>
 
diff --git a/src/com/android/contacts/list/ContactListItemView.java b/src/com/android/contacts/list/ContactListItemView.java
index 295c2a1..49957dc 100644
--- a/src/com/android/contacts/list/ContactListItemView.java
+++ b/src/com/android/contacts/list/ContactListItemView.java
@@ -174,9 +174,14 @@
     private int mNameTextViewHeight;
     private int mPhoneticNameTextViewHeight;
     private int mLabelTextViewHeight;
+    private int mDataViewHeight;
     private int mSnippetTextViewHeight;
     private int mStatusTextViewHeight;
 
+    // Holds Math.max(mLabelTextViewHeight, mDataViewHeight), assuming Label and Data share the
+    // same row.
+    private int mLabelAndDataViewMaxHeight;
+
     private OnClickListener mCallButtonClickListener;
     private CharArrayBuffer mDataBuffer = new CharArrayBuffer(128);
     private CharArrayBuffer mPhoneticNameBuffer = new CharArrayBuffer(128);
@@ -308,9 +313,20 @@
         mNameTextViewHeight = 0;
         mPhoneticNameTextViewHeight = 0;
         mLabelTextViewHeight = 0;
+        mDataViewHeight = 0;
+        mLabelAndDataViewMaxHeight = 0;
         mSnippetTextViewHeight = 0;
         mStatusTextViewHeight = 0;
 
+        // TODO: measure(0, 0) is *wrong*. At least, we should use correct width for each TextView.
+        //
+        // Reason: TextView applies ellipsis effect in this phase, while measure(0, 0) have those
+        // views prepare the effect based on "unlimited width", which makes ellipsis setting
+        // meaningless. We should pass a widthMeasureSpec with appropriate width setting.
+        // See issue 5439903.
+
+        ensurePhotoViewSize();
+
         // Go over all visible text views and add their heights to get the total height
         if (isVisible(mNameTextView)) {
             mNameTextView.measure(0, 0);
@@ -322,17 +338,29 @@
             mPhoneticNameTextViewHeight = mPhoneticNameTextView.getMeasuredHeight();
         }
 
-        if (isVisible(mLabelView)) {
-            mLabelView.measure(0, 0);
-            mLabelTextViewHeight = mLabelView.getMeasuredHeight();
-        }
-
-        // Label view height is the biggest of the label text view and the data text view
         if (isVisible(mDataView)) {
             mDataView.measure(0, 0);
-            mLabelTextViewHeight = Math.max(mLabelTextViewHeight, mDataView.getMeasuredHeight());
+            mDataViewHeight = mDataView.getMeasuredHeight();
         }
 
+        if (isVisible(mLabelView)) {
+            if (mPhotoPosition == PhotoPosition.LEFT) {
+                // Manually calculate the width now and see if ellipsis becomes effective or not.
+                // See also issue 5438757 and 5439903.
+                final int labelViewWidth = width - mExtraPaddingLeft - mExtraPaddingRight
+                        - (mPhotoViewWidth + mGapBetweenImageAndText)
+                        - mDataView.getMeasuredWidth()
+                        - mGapBetweenLabelAndData;
+                final int labelViewWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+                        labelViewWidth, MeasureSpec.AT_MOST);
+                mLabelView.measure(labelViewWidthMeasureSpec, 0);
+            } else {
+                mLabelView.measure(0, 0);
+            }
+            mLabelTextViewHeight = mLabelView.getMeasuredHeight();
+        }
+        mLabelAndDataViewMaxHeight = Math.max(mLabelTextViewHeight, mDataViewHeight);
+
         if (isVisible(mSnippetView)) {
             mSnippetView.measure(0, 0);
             mSnippetTextViewHeight = mSnippetView.getMeasuredHeight();
@@ -351,7 +379,7 @@
         }
 
         // Calculate height including padding
-        height += mNameTextViewHeight + mPhoneticNameTextViewHeight + mLabelTextViewHeight +
+        height += mNameTextViewHeight + mPhoneticNameTextViewHeight + mLabelAndDataViewMaxHeight +
                 mSnippetTextViewHeight + mStatusTextViewHeight +
                 mExtraPaddingTop + mExtraPaddingBottom;
 
@@ -360,7 +388,6 @@
         }
 
         // Make sure the height is at least as high as the photo
-        ensurePhotoViewSize();
         height = Math.max(height, mPhotoViewHeight + mExtraPaddingBottom + mExtraPaddingTop);
 
         // Add horizontal divider height
@@ -478,7 +505,7 @@
 
         // Center text vertically
         final int totalTextHeight = mNameTextViewHeight + mPhoneticNameTextViewHeight +
-                mLabelTextViewHeight + mSnippetTextViewHeight + mStatusTextViewHeight;
+                mLabelAndDataViewMaxHeight + mSnippetTextViewHeight + mStatusTextViewHeight;
         int textTopBound = (bottomBound + topBound - totalTextHeight) / 2;
 
         // Layout all text view and presence icon
@@ -524,32 +551,33 @@
             textTopBound += mPhoneticNameTextViewHeight;
         }
 
+        // Label and Data align bottom.
         if (isVisible(mLabelView)) {
             if (mPhotoPosition == PhotoPosition.LEFT) {
                 // When photo is on left, label is placed on the right edge of the list item.
                 mLabelView.layout(rightBound - mLabelView.getMeasuredWidth(),
-                        textTopBound,
+                        textTopBound + mLabelAndDataViewMaxHeight - mLabelTextViewHeight,
                         rightBound,
-                        textTopBound + mLabelTextViewHeight);
+                        textTopBound + mLabelAndDataViewMaxHeight);
             } else {
                 // When photo is on right, label is placed on the left of data view.
                 dataLeftBound = leftBound + mLabelView.getMeasuredWidth();
                 mLabelView.layout(leftBound,
-                        textTopBound,
+                        textTopBound + mLabelAndDataViewMaxHeight - mLabelTextViewHeight,
                         dataLeftBound,
-                        textTopBound + mLabelTextViewHeight);
+                        textTopBound + mLabelAndDataViewMaxHeight);
                 dataLeftBound += mGapBetweenLabelAndData;
             }
         }
 
         if (isVisible(mDataView)) {
             mDataView.layout(dataLeftBound,
-                    textTopBound,
+                    textTopBound + mLabelAndDataViewMaxHeight - mDataViewHeight,
                     rightBound,
-                    textTopBound + mLabelTextViewHeight);
+                    textTopBound + mLabelAndDataViewMaxHeight);
         }
         if (isVisible(mLabelView) || isVisible(mDataView)) {
-            textTopBound += mLabelTextViewHeight;
+            textTopBound += mLabelAndDataViewMaxHeight;
         }
 
         if (isVisible(mSnippetView)) {
@@ -919,6 +947,7 @@
             mLabelView.setTextAppearance(mContext, android.R.style.TextAppearance_Small);
             if (mPhotoPosition == PhotoPosition.LEFT) {
                 mLabelView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mCountViewTextSize);
+                mLabelView.setEllipsize(TruncateAt.MIDDLE);
                 mLabelView.setAllCaps(true);
             } else {
                 mLabelView.setTypeface(mLabelView.getTypeface(), Typeface.BOLD);