Home | History | Annotate | Download | only in widget
      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