InterpolatingLayout.java revision 7d3b91577f84a4f5092d28ed0f3cfe7e0df32696
12ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov/* 22ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * Copyright (C) 2010 The Android Open Source Project 32ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * 42ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License"); 52ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * you may not use this file except in compliance with the License. 62ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * You may obtain a copy of the License at 72ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * 82ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * http://www.apache.org/licenses/LICENSE-2.0 92ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * 102ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * Unless required by applicable law or agreed to in writing, software 112ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS, 122ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * See the License for the specific language governing permissions and 142ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * limitations under the License. 152ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov */ 162ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 172ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikovpackage com.android.contacts.widget; 182ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 192ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikovimport android.content.Context; 202ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikovimport android.content.res.TypedArray; 215c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikovimport android.graphics.Rect; 222ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikovimport android.util.AttributeSet; 235c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikovimport android.view.Gravity; 242ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikovimport android.view.View; 252ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikovimport android.view.ViewGroup; 265c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikovimport android.widget.LinearLayout; 272ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 28e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R; 29e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng 302ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov/** 312ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * Layout similar to LinearLayout that allows a child to specify examples of 322ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * desired size depending on the parent size. For example if the widget wants to 332ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * be 100dip when parent is 200dip and 110dip when parent is 400dip, the layout 342ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * will ensure these requirements and interpolate for other parent sizes. 352ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * You can also specify minWidth for each child. You can have at most one 362ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * child with layout_width="match_parent" - it will take the entire remaining 372ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * space. 382ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov */ 392ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikovpublic class InterpolatingLayout extends ViewGroup { 402ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 415c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov private Rect mInRect = new Rect(); 425c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov private Rect mOutRect = new Rect(); 435c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov 442ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov public InterpolatingLayout(Context context) { 452ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov super(context); 462ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 472ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 482ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov public InterpolatingLayout(Context context, AttributeSet attrs) { 492ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov super(context, attrs); 502ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 512ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 522ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov public InterpolatingLayout(Context context, AttributeSet attrs, int defStyle) { 532ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov super(context, attrs, defStyle); 542ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 552ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 565c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov public final static class LayoutParams extends LinearLayout.LayoutParams { 572ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 582ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov public int narrowParentWidth; 592ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov public int narrowWidth; 6075d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov public int narrowMarginLeft; 6175d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov public int narrowPaddingLeft; 6275d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov public int narrowMarginRight; 6375d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov public int narrowPaddingRight; 642ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov public int wideParentWidth; 652ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov public int wideWidth; 6675d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov public int wideMarginLeft; 6775d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov public int widePaddingLeft; 6875d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov public int wideMarginRight; 6975d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov public int widePaddingRight; 702ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov private float widthMultiplier; 712ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov private int widthConstant; 722ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov private float leftMarginMultiplier; 732ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov private int leftMarginConstant; 74bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov private float leftPaddingMultiplier; 75bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov private int leftPaddingConstant; 762ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov private float rightMarginMultiplier; 772ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov private int rightMarginConstant; 78bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov private float rightPaddingMultiplier; 79bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov private int rightPaddingConstant; 802ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 812ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov public LayoutParams(Context c, AttributeSet attrs) { 822ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov super(c, attrs); 832ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.InterpolatingLayout_Layout); 842ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 852ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov narrowParentWidth = a.getDimensionPixelSize( 862ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov R.styleable.InterpolatingLayout_Layout_layout_narrowParentWidth, -1); 872ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov narrowWidth = a.getDimensionPixelSize( 882ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov R.styleable.InterpolatingLayout_Layout_layout_narrowWidth, -1); 8975d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov narrowMarginLeft = a.getDimensionPixelSize( 9075d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov R.styleable.InterpolatingLayout_Layout_layout_narrowMarginLeft, -1); 9175d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov narrowPaddingLeft = a.getDimensionPixelSize( 9275d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov R.styleable.InterpolatingLayout_Layout_layout_narrowPaddingLeft, -1); 9375d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov narrowMarginRight = a.getDimensionPixelSize( 9475d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov R.styleable.InterpolatingLayout_Layout_layout_narrowMarginRight, -1); 9575d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov narrowPaddingRight = a.getDimensionPixelSize( 9675d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov R.styleable.InterpolatingLayout_Layout_layout_narrowPaddingRight, -1); 972ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov wideParentWidth = a.getDimensionPixelSize( 982ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov R.styleable.InterpolatingLayout_Layout_layout_wideParentWidth, -1); 992ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov wideWidth = a.getDimensionPixelSize( 1002ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov R.styleable.InterpolatingLayout_Layout_layout_wideWidth, -1); 10175d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov wideMarginLeft = a.getDimensionPixelSize( 10275d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov R.styleable.InterpolatingLayout_Layout_layout_wideMarginLeft, -1); 10375d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov widePaddingLeft = a.getDimensionPixelSize( 10475d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov R.styleable.InterpolatingLayout_Layout_layout_widePaddingLeft, -1); 10575d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov wideMarginRight = a.getDimensionPixelSize( 10675d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov R.styleable.InterpolatingLayout_Layout_layout_wideMarginRight, -1); 10775d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov widePaddingRight = a.getDimensionPixelSize( 10875d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov R.styleable.InterpolatingLayout_Layout_layout_widePaddingRight, -1); 1092ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 1102ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov a.recycle(); 1112ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 1122ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov if (narrowWidth != -1) { 1132ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov widthMultiplier = (float) (wideWidth - narrowWidth) 1142ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov / (wideParentWidth - narrowParentWidth); 1152ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov widthConstant = (int) (narrowWidth - narrowParentWidth * widthMultiplier); 1162ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 1172ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 11875d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov if (narrowMarginLeft != -1) { 11975d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov leftMarginMultiplier = (float) (wideMarginLeft - narrowMarginLeft) 1202ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov / (wideParentWidth - narrowParentWidth); 12175d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov leftMarginConstant = (int) (narrowMarginLeft - narrowParentWidth 1222ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * leftMarginMultiplier); 1232ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 1242ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 12575d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov if (narrowPaddingLeft != -1) { 12675d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov leftPaddingMultiplier = (float) (widePaddingLeft - narrowPaddingLeft) 127bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov / (wideParentWidth - narrowParentWidth); 12875d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov leftPaddingConstant = (int) (narrowPaddingLeft - narrowParentWidth 129bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov * leftPaddingMultiplier); 130bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov } 131bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov 13275d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov if (narrowMarginRight != -1) { 13375d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov rightMarginMultiplier = (float) (wideMarginRight - narrowMarginRight) 1342ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov / (wideParentWidth - narrowParentWidth); 13575d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov rightMarginConstant = (int) (narrowMarginRight - narrowParentWidth 1362ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov * rightMarginMultiplier); 1372ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 138bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov 13975d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov if (narrowPaddingRight != -1) { 14075d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov rightPaddingMultiplier = (float) (widePaddingRight - narrowPaddingRight) 141bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov / (wideParentWidth - narrowParentWidth); 14275d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov rightPaddingConstant = (int) (narrowPaddingRight - narrowParentWidth 143bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov * rightPaddingMultiplier); 144bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov } 1452ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 1462ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 1472ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov public LayoutParams(int width, int height) { 1482ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov super(width, height); 1492ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 1502ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 1512ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov public LayoutParams(MarginLayoutParams source) { 1522ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov super(source); 1532ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 1542ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 1552ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov public int resolveWidth(int parentSize) { 1562ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov if (narrowWidth == -1) { 1572ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov return width; 1582ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } else { 1592ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov int w = (int) (parentSize * widthMultiplier) + widthConstant; 1602ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov return w <= 0 ? WRAP_CONTENT : w; 1612ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 1622ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 1632ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 1642ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov public int resolveLeftMargin(int parentSize) { 16575d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov if (narrowMarginLeft == -1) { 1662ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov return leftMargin; 1672ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } else { 1682ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov int w = (int) (parentSize * leftMarginMultiplier) + leftMarginConstant; 1692ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov return w < 0 ? 0 : w; 1702ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 1712ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 1722ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 173bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov public int resolveLeftPadding(int parentSize) { 174bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov int w = (int) (parentSize * leftPaddingMultiplier) + leftPaddingConstant; 175bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov return w < 0 ? 0 : w; 176bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov } 177bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov 1782ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov public int resolveRightMargin(int parentSize) { 17975d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov if (narrowMarginRight == -1) { 1802ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov return rightMargin; 1812ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } else { 1822ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov int w = (int) (parentSize * rightMarginMultiplier) + rightMarginConstant; 1832ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov return w < 0 ? 0 : w; 1842ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 1852ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 186bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov 187bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov public int resolveRightPadding(int parentSize) { 188bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov int w = (int) (parentSize * rightPaddingMultiplier) + rightPaddingConstant; 189bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov return w < 0 ? 0 : w; 190bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov } 1912ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 1922ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 1932ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov @Override 1942ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov public LayoutParams generateLayoutParams(AttributeSet attrs) { 1952ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov return new LayoutParams(getContext(), attrs); 1962ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 1972ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 1982ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov @Override 1992ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov protected LayoutParams generateDefaultLayoutParams() { 2002ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 2012ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 2022ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 2032ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov @Override 2042ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 2055c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov int parentWidth = MeasureSpec.getSize(widthMeasureSpec); 2065c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov int parentHeight = MeasureSpec.getSize(heightMeasureSpec); 2072ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 2082ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov int width = 0; 2092ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov int height = 0; 2102ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 2112ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov View fillChild = null; 2122ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov int count = getChildCount(); 2132ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov for (int i = 0; i < count; i++) { 2142ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov View child = getChildAt(i); 2152ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov if (child.getVisibility() == View.GONE) { 2162ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov continue; 2172ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 2182ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 2192ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov LayoutParams params = (LayoutParams) child.getLayoutParams(); 2202ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov if (params.width == LayoutParams.MATCH_PARENT) { 2212ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov if (fillChild != null) { 2222ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov throw new RuntimeException( 2232ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov "Interpolating layout allows at most one child" 2242ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov + " with layout_width='match_parent'"); 2252ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 2262ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov fillChild = child; 2272ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } else { 2285c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov int childWidth = params.resolveWidth(parentWidth); 2295c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov int childWidthMeasureSpec; 2305c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov switch (childWidth) { 2315c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov case LayoutParams.WRAP_CONTENT: 2325c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov childWidthMeasureSpec = MeasureSpec.UNSPECIFIED; 2335c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov break; 2345c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov default: 2355c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov childWidthMeasureSpec = MeasureSpec.makeMeasureSpec( 2365c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov childWidth, MeasureSpec.EXACTLY); 2375c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov break; 2385c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov } 2395c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov 2405c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov int childHeightMeasureSpec; 2415c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov switch (params.height) { 2425c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov case LayoutParams.WRAP_CONTENT: 2435c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov childHeightMeasureSpec = MeasureSpec.UNSPECIFIED; 2445c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov break; 2455c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov case LayoutParams.MATCH_PARENT: 2465c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov childHeightMeasureSpec = MeasureSpec.makeMeasureSpec( 24765f8cae5f848b63ae695da63b56fc9270513078aDmitri Plotnikov parentHeight - params.topMargin - params.bottomMargin, 24865f8cae5f848b63ae695da63b56fc9270513078aDmitri Plotnikov MeasureSpec.EXACTLY); 2495c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov break; 2505c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov default: 2515c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov childHeightMeasureSpec = MeasureSpec.makeMeasureSpec( 2525c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov params.height, MeasureSpec.EXACTLY); 2535c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov break; 2545c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov } 2555c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov 2565c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov child.measure(childWidthMeasureSpec, childHeightMeasureSpec); 2572ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov width += child.getMeasuredWidth(); 2582ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov height = Math.max(child.getMeasuredHeight(), height); 2592ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 2602ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 2615c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov width += params.resolveLeftMargin(parentWidth) + params.resolveRightMargin(parentWidth); 2622ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 2632ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 2642ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov if (fillChild != null) { 2655c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov int remainder = parentWidth - width; 2662ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov int childMeasureSpec = remainder > 0 2672ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov ? MeasureSpec.makeMeasureSpec(remainder, MeasureSpec.EXACTLY) 2682ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov : MeasureSpec.UNSPECIFIED; 2692ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov fillChild.measure(childMeasureSpec, heightMeasureSpec); 2702ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov width += fillChild.getMeasuredWidth(); 2712ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov height = Math.max(fillChild.getMeasuredHeight(), height); 2722ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 2732ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 2742ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov setMeasuredDimension( 2752ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov resolveSize(width, widthMeasureSpec), resolveSize(height, heightMeasureSpec)); 2762ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 2772ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 2782ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov @Override 2792ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 2802ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov int offset = 0; 2812ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov int width = right - left; 2822ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov int count = getChildCount(); 2832ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov for (int i = 0; i < count; i++) { 2842ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov View child = getChildAt(i); 2852ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov 28676dd128627beef2e0516e6742280bd15fc68e59fFrank Sposaro if (child.getVisibility() == View.GONE) { 28776dd128627beef2e0516e6742280bd15fc68e59fFrank Sposaro continue; 28876dd128627beef2e0516e6742280bd15fc68e59fFrank Sposaro } 28976dd128627beef2e0516e6742280bd15fc68e59fFrank Sposaro 2902ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov LayoutParams params = (LayoutParams) child.getLayoutParams(); 2915c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov int gravity = params.gravity; 2925c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov if (gravity == -1) { 2937d3b91577f84a4f5092d28ed0f3cfe7e0df32696Fabrice Di Meglio gravity = Gravity.START | Gravity.TOP; 2945c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov } 2955c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov 29675d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov if (params.narrowPaddingLeft != -1 || params.narrowPaddingRight != -1) { 29775d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov int leftPadding = params.narrowPaddingLeft == -1 ? child.getPaddingLeft() 298bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov : params.resolveLeftPadding(width); 29975d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov int rightPadding = params.narrowPaddingRight == -1 ? child.getPaddingRight() 300bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov : params.resolveRightPadding(width); 301bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov child.setPadding( 302bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov leftPadding, child.getPaddingTop(), rightPadding, child.getPaddingBottom()); 303bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov } 304bb0788a8a052cb3baf8fdc20fcf97d77b94e12abDmitri Plotnikov 3055c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov int leftMargin = params.resolveLeftMargin(width); 3065c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov int rightMargin = params.resolveRightMargin(width); 3075c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov 3085c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov mInRect.set(offset + leftMargin, params.topMargin, 309b18624f0cbca15e6a515316f7046ad814d54c970Dmitri Plotnikov right - rightMargin, bottom - params.bottomMargin); 3105c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov 31175d6cae5c617ec15fa58aea5a6522e367f1168baDmitri Plotnikov Gravity.apply(gravity, child.getMeasuredWidth(), child.getMeasuredHeight(), 3125c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov mInRect, mOutRect); 3135c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov child.layout(mOutRect.left, mOutRect.top, mOutRect.right, mOutRect.bottom); 3145c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov 3155c0935b29be4d454ab8f6e89ae94e792ff35982bDmitri Plotnikov offset = mOutRect.right + rightMargin; 3162ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 3172ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov } 3182ddba01a5fe79173d22dcd125673313e7007e6ecDmitri Plotnikov} 319