1 package com.android.deskclock.widget; 2 3 import android.content.Context; 4 import android.util.AttributeSet; 5 import android.view.View; 6 import android.widget.LinearLayout; 7 import android.widget.TextView; 8 9 /** 10 * When this layout is in the Horizontal orientation and one and only one child 11 * is a TextView with a non-null android:ellipsize, this layout will reduce 12 * android:maxWidth of that TextView to ensure the other children are within the 13 * layout. This layout has no effect if the children have weights. 14 */ 15 public class EllipsizeLayout extends LinearLayout { 16 17 public EllipsizeLayout(Context context) { 18 this(context, null); 19 } 20 21 public EllipsizeLayout(Context context, AttributeSet attrs) { 22 super(context, attrs); 23 } 24 25 @Override 26 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 27 if (getOrientation() == HORIZONTAL 28 && (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY)) { 29 int totalLength = 0; 30 boolean outOfSpec = false; 31 TextView ellipView = null; 32 final int count = getChildCount(); 33 34 for (int ii = 0; ii < count && !outOfSpec; ++ii) { 35 final View child = getChildAt(ii); 36 if (child != null && child.getVisibility() != GONE) { 37 if (child instanceof TextView) { 38 final TextView tv = (TextView) child; 39 if (tv.getEllipsize() != null) { 40 if (ellipView == null) { 41 ellipView = tv; 42 // clear maxWidth on mEllipView before measure 43 ellipView.setMaxWidth(Integer.MAX_VALUE); 44 } else { 45 // TODO: support multiple android:ellipsize 46 outOfSpec = true; 47 } 48 } 49 } 50 final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child 51 .getLayoutParams(); 52 outOfSpec |= (lp.weight > 0f); 53 measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0); 54 totalLength += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; 55 } 56 } 57 outOfSpec |= (ellipView == null) || (totalLength == 0); 58 final int parentWidth = MeasureSpec.getSize(widthMeasureSpec); 59 60 if (!outOfSpec && totalLength > parentWidth) { 61 int maxWidth = ellipView.getMeasuredWidth() - (totalLength - parentWidth); 62 // TODO: Respect android:minWidth (easy with @TargetApi(16)) 63 int minWidth = 0; 64 if (maxWidth < minWidth) { 65 maxWidth = minWidth; 66 } 67 ellipView.setMaxWidth(maxWidth); 68 } 69 } 70 71 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 72 } 73 } 74