149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes/* 249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Copyright (C) 2014 The Android Open Source Project 349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * you may not use this file except in compliance with the License. 649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * You may obtain a copy of the License at 749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * http://www.apache.org/licenses/LICENSE-2.0 949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 1049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Unless required by applicable law or agreed to in writing, software 1149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * distributed under the License is distributed on an "AS IS" BASIS, 1249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * See the License for the specific language governing permissions and 1449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * limitations under the License. 1549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 1649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 1749c78900da0d43140fb602431fb93212bd7f6c70Chris Banespackage android.support.v7.widget; 1849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 198e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikasimport static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP; 208e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas 2149c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.content.Context; 2249c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.content.res.TypedArray; 2349c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.graphics.Canvas; 2449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.graphics.drawable.Drawable; 2549c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.os.Build; 2649c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.annotation.IntDef; 27c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viveretteimport android.support.annotation.RestrictTo; 2849c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.GravityCompat; 2949c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ViewCompat; 3049c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.appcompat.R; 3149c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.util.AttributeSet; 3249c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.Gravity; 3349c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.View; 3449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.ViewGroup; 3549c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.accessibility.AccessibilityEvent; 3649c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.accessibility.AccessibilityNodeInfo; 3749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 3849c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport java.lang.annotation.Retention; 3949c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport java.lang.annotation.RetentionPolicy; 4049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 4149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 4249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes/** 4349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * A Layout that arranges its children in a single column or a single row. The direction of 4449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * the row can be set by calling {@link #setOrientation(int) setOrientation()}. 4549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * You can also specify gravity, which specifies the alignment of all the child elements by 4649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * calling {@link #setGravity(int) setGravity()} or specify that specific children 4749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * grow to fill up any remaining space in the layout by setting the <em>weight</em> member of 4849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * {@link LinearLayoutCompat.LayoutParams LinearLayoutCompat.LayoutParams}. 4949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * The default orientation is horizontal. 5049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 5149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * <p>See the <a href="{@docRoot}guide/topics/ui/layout/linear.html">Linear Layout</a> 5249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * guide.</p> 5349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 5449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * <p> 55b5837eb1118cfd6e583749bc0a4e72af10c7eb0cChris Banes * Also see {@link LinearLayoutCompat.LayoutParams} for layout attributes </p> 5649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 5749c78900da0d43140fb602431fb93212bd7f6c70Chris Banespublic class LinearLayoutCompat extends ViewGroup { 5849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** @hide */ 598e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas @RestrictTo(LIBRARY_GROUP) 6049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @IntDef({HORIZONTAL, VERTICAL}) 6149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Retention(RetentionPolicy.SOURCE) 6249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public @interface OrientationMode {} 6349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 6449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public static final int HORIZONTAL = 0; 6549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public static final int VERTICAL = 1; 6649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 6749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** @hide */ 688e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas @RestrictTo(LIBRARY_GROUP) 6949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @IntDef(flag = true, 7049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes value = { 7149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes SHOW_DIVIDER_NONE, 7249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes SHOW_DIVIDER_BEGINNING, 7349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes SHOW_DIVIDER_MIDDLE, 7449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes SHOW_DIVIDER_END 7549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes }) 7649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Retention(RetentionPolicy.SOURCE) 7749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public @interface DividerMode {} 7849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 7949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 8049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Don't show any dividers. 8149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 8249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public static final int SHOW_DIVIDER_NONE = 0; 8349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 8449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Show a divider at the beginning of the group. 8549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 8649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public static final int SHOW_DIVIDER_BEGINNING = 1; 8749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 8849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Show dividers between each item in the group. 8949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 9049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public static final int SHOW_DIVIDER_MIDDLE = 2; 9149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 9249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Show a divider at the end of the group. 9349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 9449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public static final int SHOW_DIVIDER_END = 4; 9549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 9649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 9749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Whether the children of this layout are baseline aligned. Only applicable 9849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * if {@link #mOrientation} is horizontal. 9949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 10049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private boolean mBaselineAligned = true; 10149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 10249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 10349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * If this layout is part of another layout that is baseline aligned, 10449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * use the child at this index as the baseline. 10549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 10649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Note: this is orthogonal to {@link #mBaselineAligned}, which is concerned 10749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * with whether the children of this layout are baseline aligned. 10849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 10949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int mBaselineAlignedChildIndex = -1; 11049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 11149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 11249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * The additional offset to the child's baseline. 11349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * We'll calculate the baseline of this layout as we measure vertically; for 11449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * horizontal linear layouts, the offset of 0 is appropriate. 11549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 11649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int mBaselineChildTop = 0; 11749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 11849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int mOrientation; 11949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 12049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int mGravity = GravityCompat.START | Gravity.TOP; 12149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 12249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int mTotalLength; 12349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 12449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private float mWeightSum; 12549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 12649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private boolean mUseLargestChild; 12749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 12849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int[] mMaxAscent; 12949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int[] mMaxDescent; 13049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 13149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private static final int VERTICAL_GRAVITY_COUNT = 4; 13249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 13349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private static final int INDEX_CENTER_VERTICAL = 0; 13449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private static final int INDEX_TOP = 1; 13549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private static final int INDEX_BOTTOM = 2; 13649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private static final int INDEX_FILL = 3; 13749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 13849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private Drawable mDivider; 13949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int mDividerWidth; 14049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int mDividerHeight; 14149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int mShowDividers; 14249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private int mDividerPadding; 14349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 14449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LinearLayoutCompat(Context context) { 14549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes this(context, null); 14649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 14749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 14849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LinearLayoutCompat(Context context, AttributeSet attrs) { 14949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes this(context, attrs, 0); 15049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 15149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 15249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LinearLayoutCompat(Context context, AttributeSet attrs, int defStyleAttr) { 15349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(context, attrs, defStyleAttr); 15449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 155c497221ee0e2e873f49653ff1a046df2e5276759Chris Banes final TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attrs, 156c497221ee0e2e873f49653ff1a046df2e5276759Chris Banes R.styleable.LinearLayoutCompat, defStyleAttr, 0); 15749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 15849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int index = a.getInt(R.styleable.LinearLayoutCompat_android_orientation, -1); 15949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (index >= 0) { 16049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setOrientation(index); 16149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 16249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 16349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes index = a.getInt(R.styleable.LinearLayoutCompat_android_gravity, -1); 16449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (index >= 0) { 16549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setGravity(index); 16649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 16749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 16849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes boolean baselineAligned = a.getBoolean(R.styleable.LinearLayoutCompat_android_baselineAligned, true); 16949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!baselineAligned) { 17049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setBaselineAligned(baselineAligned); 17149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 17249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 17349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mWeightSum = a.getFloat(R.styleable.LinearLayoutCompat_android_weightSum, -1.0f); 17449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 17549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mBaselineAlignedChildIndex = 17649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes a.getInt(R.styleable.LinearLayoutCompat_android_baselineAlignedChildIndex, -1); 17749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 17849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mUseLargestChild = a.getBoolean(R.styleable.LinearLayoutCompat_measureWithLargestChild, false); 17949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 18049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setDividerDrawable(a.getDrawable(R.styleable.LinearLayoutCompat_divider)); 18149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mShowDividers = a.getInt(R.styleable.LinearLayoutCompat_showDividers, SHOW_DIVIDER_NONE); 18249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDividerPadding = a.getDimensionPixelSize(R.styleable.LinearLayoutCompat_dividerPadding, 0); 18349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 18449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes a.recycle(); 18549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 18649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 18749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 18849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Set how dividers should be shown between items in this layout 18949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 19049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param showDividers One or more of {@link #SHOW_DIVIDER_BEGINNING}, 19149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * {@link #SHOW_DIVIDER_MIDDLE}, or {@link #SHOW_DIVIDER_END}, 19249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * or {@link #SHOW_DIVIDER_NONE} to show no dividers. 19349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 19449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setShowDividers(@DividerMode int showDividers) { 19549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (showDividers != mShowDividers) { 19649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes requestLayout(); 19749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 19849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mShowDividers = showDividers; 19949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 20049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 20149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 20249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean shouldDelayChildPressedState() { 20349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return false; 20449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 20549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 20649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 20749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return A flag set indicating how dividers should be shown around items. 20849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #setShowDividers(int) 20949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 21049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @DividerMode 21149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public int getShowDividers() { 21249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mShowDividers; 21349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 21449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 21549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 21649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return the divider Drawable that will divide each item. 21749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 21849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #setDividerDrawable(Drawable) 21949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 22049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public Drawable getDividerDrawable() { 22149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDivider; 22249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 22349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 22449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 22549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Set a drawable to be used as a divider between items. 22649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 22749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param divider Drawable that will divide each item. 22849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 22949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #setShowDividers(int) 23049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 23149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setDividerDrawable(Drawable divider) { 23249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (divider == mDivider) { 23349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return; 23449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 23549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDivider = divider; 23649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (divider != null) { 23749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDividerWidth = divider.getIntrinsicWidth(); 23849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDividerHeight = divider.getIntrinsicHeight(); 23949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 24049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDividerWidth = 0; 24149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDividerHeight = 0; 24249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 24349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setWillNotDraw(divider == null); 24449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes requestLayout(); 24549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 24649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 24749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 24849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Set padding displayed on both ends of dividers. 24949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 25049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param padding Padding value in pixels that will be applied to each end 25149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 25249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #setShowDividers(int) 25349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #setDividerDrawable(Drawable) 25449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #getDividerPadding() 25549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 25649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setDividerPadding(int padding) { 25749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDividerPadding = padding; 25849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 25949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 26049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 26149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Get the padding size used to inset dividers in pixels 26249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 26349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #setShowDividers(int) 26449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #setDividerDrawable(Drawable) 26549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #setDividerPadding(int) 26649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 26749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public int getDividerPadding() { 26849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDividerPadding; 26949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 27049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 27149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 27249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Get the width of the current divider drawable. 27349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 27449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @hide Used internally by framework. 27549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 2768e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas @RestrictTo(LIBRARY_GROUP) 27749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public int getDividerWidth() { 27849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mDividerWidth; 27949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 28049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 28149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 28249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected void onDraw(Canvas canvas) { 28349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mDivider == null) { 28449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return; 28549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 28649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 28749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mOrientation == VERTICAL) { 28849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes drawDividersVertical(canvas); 28949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 29049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes drawDividersHorizontal(canvas); 29149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 29249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 29349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 29449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void drawDividersVertical(Canvas canvas) { 29549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int count = getVirtualChildCount(); 29649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; i++) { 29749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(i); 29849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 29949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child != null && child.getVisibility() != GONE) { 30049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (hasDividerBeforeChildAt(i)) { 30149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 30249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int top = child.getTop() - lp.topMargin - mDividerHeight; 30349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes drawHorizontalDivider(canvas, top); 30449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 30549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 30649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 30749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 30849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (hasDividerBeforeChildAt(count)) { 30949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(count - 1); 31049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int bottom = 0; 31149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child == null) { 31249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes bottom = getHeight() - getPaddingBottom() - mDividerHeight; 31349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 31449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 31549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes bottom = child.getBottom() + lp.bottomMargin; 31649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 31749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes drawHorizontalDivider(canvas, bottom); 31849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 31949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 32049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 32149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void drawDividersHorizontal(Canvas canvas) { 32249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int count = getVirtualChildCount(); 32349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final boolean isLayoutRtl = ViewUtils.isLayoutRtl(this); 32449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; i++) { 32549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(i); 32649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 32749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child != null && child.getVisibility() != GONE) { 32849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (hasDividerBeforeChildAt(i)) { 32949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 33049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int position; 33149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (isLayoutRtl) { 33249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes position = child.getRight() + lp.rightMargin; 33349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 33449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes position = child.getLeft() - lp.leftMargin - mDividerWidth; 33549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 33649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes drawVerticalDivider(canvas, position); 33749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 33849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 33949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 34049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 34149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (hasDividerBeforeChildAt(count)) { 34249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(count - 1); 34349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int position; 34449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child == null) { 34549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (isLayoutRtl) { 34649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes position = getPaddingLeft(); 34749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 34849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes position = getWidth() - getPaddingRight() - mDividerWidth; 34949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 35049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 35149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final LayoutParams lp = (LayoutParams) child.getLayoutParams(); 35249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (isLayoutRtl) { 35349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes position = child.getLeft() - lp.leftMargin - mDividerWidth; 35449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 35549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes position = child.getRight() + lp.rightMargin; 35649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 35749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 35849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes drawVerticalDivider(canvas, position); 35949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 36049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 36149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 36249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void drawHorizontalDivider(Canvas canvas, int top) { 36349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDivider.setBounds(getPaddingLeft() + mDividerPadding, top, 36449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes getWidth() - getPaddingRight() - mDividerPadding, top + mDividerHeight); 36549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDivider.draw(canvas); 36649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 36749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 36849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void drawVerticalDivider(Canvas canvas, int left) { 36949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDivider.setBounds(left, getPaddingTop() + mDividerPadding, 37049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes left + mDividerWidth, getHeight() - getPaddingBottom() - mDividerPadding); 37149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDivider.draw(canvas); 37249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 37349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 37449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 37549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * <p>Indicates whether widgets contained within this layout are aligned 37649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * on their baseline or not.</p> 37749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 37849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return true when widgets are baseline-aligned, false otherwise 37949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 38049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean isBaselineAligned() { 38149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mBaselineAligned; 38249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 38349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 38449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 38549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * <p>Defines whether widgets contained in this layout are 38649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * baseline-aligned or not.</p> 38749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 38849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param baselineAligned true to align widgets on their baseline, 38949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * false otherwise 39049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 39149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setBaselineAligned(boolean baselineAligned) { 39249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mBaselineAligned = baselineAligned; 39349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 39449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 39549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 39649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * When true, all children with a weight will be considered having 39749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * the minimum size of the largest child. If false, all children are 39849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * measured normally. 39949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 40049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return True to measure children with a weight using the minimum 40149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * size of the largest child, false otherwise. 40249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 40349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public boolean isMeasureWithLargestChildEnabled() { 40449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mUseLargestChild; 40549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 40649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 40749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 40849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * When set to true, all children with a weight will be considered having 40949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * the minimum size of the largest child. If false, all children are 41049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * measured normally. 41149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 41249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Disabled by default. 41349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 41449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param enabled True to measure children with a weight using the 41549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * minimum size of the largest child, false otherwise. 41649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 41749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setMeasureWithLargestChildEnabled(boolean enabled) { 41849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mUseLargestChild = enabled; 41949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 42049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 42149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 42249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public int getBaseline() { 42349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mBaselineAlignedChildIndex < 0) { 42449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return super.getBaseline(); 42549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 42649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 42749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (getChildCount() <= mBaselineAlignedChildIndex) { 42849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes throw new RuntimeException("mBaselineAlignedChildIndex of LinearLayout " 42949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes + "set to an index that is out of bounds."); 43049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 43149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 43249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getChildAt(mBaselineAlignedChildIndex); 43349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int childBaseline = child.getBaseline(); 43449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 43549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (childBaseline == -1) { 43649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mBaselineAlignedChildIndex == 0) { 43749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // this is just the default case, safe to return -1 43849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return -1; 43949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 44049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // the user picked an index that points to something that doesn't 44149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // know how to calculate its baseline. 44249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes throw new RuntimeException("mBaselineAlignedChildIndex of LinearLayout " 44349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes + "points to a View that doesn't know how to get its baseline."); 44449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 44549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 44649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // TODO: This should try to take into account the virtual offsets 44749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // (See getNextLocationOffset and getLocationOffset) 44849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // We should add to childTop: 44949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // sum([getNextLocationOffset(getChildAt(i)) / i < mBaselineAlignedChildIndex]) 45049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // and also add: 45149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // getLocationOffset(child) 45249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childTop = mBaselineChildTop; 45349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 45449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mOrientation == VERTICAL) { 45549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int majorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK; 45649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (majorGravity != Gravity.TOP) { 45749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes switch (majorGravity) { 45849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Gravity.BOTTOM: 45949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop = getBottom() - getTop() - getPaddingBottom() - mTotalLength; 46049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 46149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 46249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Gravity.CENTER_VERTICAL: 46349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop += ((getBottom() - getTop() - getPaddingTop() - getPaddingBottom()) - 46449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength) / 2; 46549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 46649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 46749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 46849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 46949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 47049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes LinearLayoutCompat.LayoutParams lp = (LinearLayoutCompat.LayoutParams) child.getLayoutParams(); 47149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return childTop + lp.topMargin + childBaseline; 47249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 47349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 47449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 47549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return The index of the child that will be used if this layout is 47649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * part of a larger layout that is baseline aligned, or -1 if none has 47749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * been set. 47849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 47949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public int getBaselineAlignedChildIndex() { 48049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mBaselineAlignedChildIndex; 48149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 48249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 48349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 48449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param i The index of the child that will be used if this layout is 48549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * part of a larger layout that is baseline aligned. 48649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 48749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setBaselineAlignedChildIndex(int i) { 48849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if ((i < 0) || (i >= getChildCount())) { 48949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes throw new IllegalArgumentException("base aligned child index out " 49049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes + "of range (0, " + getChildCount() + ")"); 49149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 49249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mBaselineAlignedChildIndex = i; 49349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 49449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 49549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 496c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas * <p>Returns the view at the specified index. This method can be overridden 49749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * to take into account virtual children. Refer to 49849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * {@link android.widget.TableLayout} and {@link android.widget.TableRow} 49949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * for an example.</p> 50049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 50149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param index the child's index 50249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return the child at the specified index 50349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 50449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes View getVirtualChildAt(int index) { 50549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return getChildAt(index); 50649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 50749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 50849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 50949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * <p>Returns the virtual number of children. This number might be different 51049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * than the actual number of children if the layout can hold virtual 51149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * children. Refer to 51249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * {@link android.widget.TableLayout} and {@link android.widget.TableRow} 51349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * for an example.</p> 51449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 51549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return the virtual number of children 51649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 51749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int getVirtualChildCount() { 51849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return getChildCount(); 51949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 52049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 52149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 52249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Returns the desired weights sum. 52349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 52449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return A number greater than 0.0f if the weight sum is defined, or 52549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * a number lower than or equals to 0.0f if not weight sum is 52649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * to be used. 52749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 52849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public float getWeightSum() { 52949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mWeightSum; 53049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 53149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 53249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 53349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Defines the desired weights sum. If unspecified the weights sum is computed 53449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * at layout time by adding the layout_weight of each child. 53549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 53649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * This can be used for instance to give a single child 50% of the total 53749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * available space by giving it a layout_weight of 0.5 and setting the 53849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * weightSum to 1.0. 53949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 54049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param weightSum a number greater than 0.0f, or a number lower than or equals 54149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * to 0.0f if the weight sum should be computed from the children's 54249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * layout_weight 54349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 54449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setWeightSum(float weightSum) { 54549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mWeightSum = Math.max(0.0f, weightSum); 54649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 54749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 54849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 54949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 55049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mOrientation == VERTICAL) { 55149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes measureVertical(widthMeasureSpec, heightMeasureSpec); 55249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 55349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes measureHorizontal(widthMeasureSpec, heightMeasureSpec); 55449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 55549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 55649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 55749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 55849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Determines where to position dividers between children. 55949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 56049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param childIndex Index of child to check for preceding divider 56149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return true if there should be a divider before the child at childIndex 56249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @hide Pending API consideration. Currently only used internally by the system. 56349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 56449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected boolean hasDividerBeforeChildAt(int childIndex) { 56549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (childIndex == 0) { 56649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return (mShowDividers & SHOW_DIVIDER_BEGINNING) != 0; 56749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else if (childIndex == getChildCount()) { 56849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return (mShowDividers & SHOW_DIVIDER_END) != 0; 56949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else if ((mShowDividers & SHOW_DIVIDER_MIDDLE) != 0) { 57049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes boolean hasVisibleViewBefore = false; 57149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = childIndex - 1; i >= 0; i--) { 57249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (getChildAt(i).getVisibility() != GONE) { 57349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes hasVisibleViewBefore = true; 57449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 57549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 57649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 57749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return hasVisibleViewBefore; 57849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 57949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return false; 58049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 58149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 58249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 58349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Measures the children when the orientation of this LinearLayout is set 58449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * to {@link #VERTICAL}. 58549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 58649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param widthMeasureSpec Horizontal space requirements as imposed by the parent. 58749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param heightMeasureSpec Vertical space requirements as imposed by the parent. 58849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 58949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #getOrientation() 59049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #setOrientation(int) 59149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #onMeasure(int, int) 59249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 59349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void measureVertical(int widthMeasureSpec, int heightMeasureSpec) { 59449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength = 0; 59549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int maxWidth = 0; 59649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childState = 0; 59749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int alternativeMaxWidth = 0; 59849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int weightedMaxWidth = 0; 59949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes boolean allFillParent = true; 60049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes float totalWeight = 0; 60149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 60249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int count = getVirtualChildCount(); 60349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 60449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 60549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 60649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 60749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes boolean matchWidth = false; 60849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes boolean skippedMeasure = false; 60949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 61049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int baselineChildIndex = mBaselineAlignedChildIndex; 61149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final boolean useLargestChild = mUseLargestChild; 61249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 61349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int largestChildHeight = Integer.MIN_VALUE; 61449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 61549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // See how tall everyone is. Also remember max width. 61649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; ++i) { 61749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(i); 61849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 61949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child == null) { 62049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += measureNullChild(i); 62149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes continue; 62249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 62349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 62449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child.getVisibility() == View.GONE) { 62549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes i += getChildrenSkipCount(child, i); 62649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes continue; 62749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 62849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 62949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (hasDividerBeforeChildAt(i)) { 63049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += mDividerHeight; 63149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 63249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 63349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes LinearLayoutCompat.LayoutParams lp = (LinearLayoutCompat.LayoutParams) child.getLayoutParams(); 63449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 63549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes totalWeight += lp.weight; 63649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 63749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (heightMode == MeasureSpec.EXACTLY && lp.height == 0 && lp.weight > 0) { 63849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Optimization: don't bother measuring children who are going to use 63949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // leftover space. These views will get measured again down below if 64049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // there is any leftover space. 64149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int totalLength = mTotalLength; 64249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength = Math.max(totalLength, totalLength + lp.topMargin + lp.bottomMargin); 64349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes skippedMeasure = true; 64449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 64549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int oldHeight = Integer.MIN_VALUE; 64649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 64749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (lp.height == 0 && lp.weight > 0) { 64849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // heightMode is either UNSPECIFIED or AT_MOST, and this 64949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // child wanted to stretch to fill available space. 65049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Translate that to WRAP_CONTENT so that it does not end up 65149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // with a height of 0 65249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes oldHeight = 0; 65349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.height = LayoutParams.WRAP_CONTENT; 65449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 65549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 65649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Determine how big this child would like to be. If this or 65749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // previous children have given a weight, then we allow it to 65849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // use all available space (and we will shrink things later 65949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // if needed). 66049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes measureChildBeforeLayout( 66149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes child, i, widthMeasureSpec, 0, heightMeasureSpec, 66249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes totalWeight == 0 ? mTotalLength : 0); 66349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 66449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (oldHeight != Integer.MIN_VALUE) { 66549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.height = oldHeight; 66649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 66749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 66849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int childHeight = child.getMeasuredHeight(); 66949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int totalLength = mTotalLength; 67049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength = Math.max(totalLength, totalLength + childHeight + lp.topMargin + 67149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.bottomMargin + getNextLocationOffset(child)); 67249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 67349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (useLargestChild) { 67449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes largestChildHeight = Math.max(childHeight, largestChildHeight); 67549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 67649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 67749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 67849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 67949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * If applicable, compute the additional offset to the child's baseline 68049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * we'll need later when asked {@link #getBaseline}. 68149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 68249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if ((baselineChildIndex >= 0) && (baselineChildIndex == i + 1)) { 68349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mBaselineChildTop = mTotalLength; 68449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 68549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 68649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // if we are trying to use a child index for our baseline, the above 68749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // book keeping only works if there are no children above it with 68849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // weight. fail fast to aid the developer. 68949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (i < baselineChildIndex && lp.weight > 0) { 69049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes throw new RuntimeException("A child of LinearLayout with index " 69149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes + "less than mBaselineAlignedChildIndex has weight > 0, which " 69249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes + "won't work. Either remove the weight, or don't set " 69349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes + "mBaselineAlignedChildIndex."); 69449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 69549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 69649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes boolean matchWidthLocally = false; 69749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (widthMode != MeasureSpec.EXACTLY && lp.width == LayoutParams.MATCH_PARENT) { 69849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // The width of the linear layout will scale, and at least one 69949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // child said it wanted to match our width. Set a flag 70049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // indicating that we need to remeasure at least that view when 70149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // we know our width. 70249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes matchWidth = true; 70349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes matchWidthLocally = true; 70449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 70549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 70649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int margin = lp.leftMargin + lp.rightMargin; 70749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int measuredWidth = child.getMeasuredWidth() + margin; 70849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxWidth = Math.max(maxWidth, measuredWidth); 709fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas childState = View.combineMeasuredStates(childState, 710fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas child.getMeasuredState()); 71149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 71249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes allFillParent = allFillParent && lp.width == LayoutParams.MATCH_PARENT; 71349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (lp.weight > 0) { 71449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /* 71549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Widths of weighted Views are bogus if we end up 71649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * remeasuring, so keep them separate. 71749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 71849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes weightedMaxWidth = Math.max(weightedMaxWidth, 71949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes matchWidthLocally ? margin : measuredWidth); 72049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 72149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes alternativeMaxWidth = Math.max(alternativeMaxWidth, 72249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes matchWidthLocally ? margin : measuredWidth); 72349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 72449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 72549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes i += getChildrenSkipCount(child, i); 72649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 72749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 72849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mTotalLength > 0 && hasDividerBeforeChildAt(count)) { 72949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += mDividerHeight; 73049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 73149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 73249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (useLargestChild && 73349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes (heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED)) { 73449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength = 0; 73549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 73649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; ++i) { 73749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(i); 73849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 73949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child == null) { 74049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += measureNullChild(i); 74149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes continue; 74249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 74349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 74449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child.getVisibility() == GONE) { 74549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes i += getChildrenSkipCount(child, i); 74649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes continue; 74749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 74849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 74949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final LinearLayoutCompat.LayoutParams lp = (LinearLayoutCompat.LayoutParams) 75049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes child.getLayoutParams(); 75149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Account for negative margins 75249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int totalLength = mTotalLength; 75349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength = Math.max(totalLength, totalLength + largestChildHeight + 75449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.topMargin + lp.bottomMargin + getNextLocationOffset(child)); 75549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 75649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 75749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 75849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Add in our padding 75949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += getPaddingTop() + getPaddingBottom(); 76049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 76149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int heightSize = mTotalLength; 76249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 76349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Check against our minimum height 76449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes heightSize = Math.max(heightSize, getSuggestedMinimumHeight()); 76549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 76649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Reconcile our calculated size with the heightMeasureSpec 767fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas int heightSizeAndState = View.resolveSizeAndState(heightSize, heightMeasureSpec, 0); 768fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas heightSize = heightSizeAndState & View.MEASURED_SIZE_MASK; 76949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 77049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Either expand children with weight to take up available space or 77149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // shrink them if they extend beyond our current bounds. If we skipped 77249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // measurement on any children, we need to measure them now. 77349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int delta = heightSize - mTotalLength; 774ad1b0e82100ee31e70040d77bfa4d847b2bf0864Aurimas Liutikas if (skippedMeasure || (delta != 0 && totalWeight > 0.0f)) { 77549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight; 77649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 77749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength = 0; 77849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 77949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; ++i) { 78049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(i); 78149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 78249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child.getVisibility() == View.GONE) { 78349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes continue; 78449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 78549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 78649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes LinearLayoutCompat.LayoutParams lp = (LinearLayoutCompat.LayoutParams) child.getLayoutParams(); 78749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 78849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes float childExtra = lp.weight; 78949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (childExtra > 0) { 79049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Child said it could absorb extra space -- give him his share 79149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int share = (int) (childExtra * delta / weightSum); 79249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes weightSum -= childExtra; 79349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes delta -= share; 79449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 79549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, 79649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes getPaddingLeft() + getPaddingRight() + 79749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.leftMargin + lp.rightMargin, lp.width); 79849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 79949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // TODO: Use a field like lp.isMeasured to figure out if this 80049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // child has been previously measured 80149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if ((lp.height != 0) || (heightMode != MeasureSpec.EXACTLY)) { 80249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // child was measured once already above... 80349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // base new measurement on stored values 80449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childHeight = child.getMeasuredHeight() + share; 80549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (childHeight < 0) { 80649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childHeight = 0; 80749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 80849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 80949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes child.measure(childWidthMeasureSpec, 81049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY)); 81149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 81249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // child was skipped in the loop above. 81349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Measure for this first time here 81449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes child.measure(childWidthMeasureSpec, 81549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MeasureSpec.makeMeasureSpec(share > 0 ? share : 0, 81649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MeasureSpec.EXACTLY)); 81749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 81849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 81949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Child may now not fit in vertical dimension. 820fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas childState = View.combineMeasuredStates(childState, 821fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas child.getMeasuredState() & (View.MEASURED_STATE_MASK 822fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas >> View.MEASURED_HEIGHT_STATE_SHIFT)); 82349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 82449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 82549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int margin = lp.leftMargin + lp.rightMargin; 82649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int measuredWidth = child.getMeasuredWidth() + margin; 82749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxWidth = Math.max(maxWidth, measuredWidth); 82849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 82949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes boolean matchWidthLocally = widthMode != MeasureSpec.EXACTLY && 83049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.width == LayoutParams.MATCH_PARENT; 83149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 83249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes alternativeMaxWidth = Math.max(alternativeMaxWidth, 83349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes matchWidthLocally ? margin : measuredWidth); 83449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 83549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes allFillParent = allFillParent && lp.width == LayoutParams.MATCH_PARENT; 83649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 83749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int totalLength = mTotalLength; 83849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength = Math.max(totalLength, totalLength + child.getMeasuredHeight() + 83949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.topMargin + lp.bottomMargin + getNextLocationOffset(child)); 84049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 84149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 84249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Add in our padding 84349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += getPaddingTop() + getPaddingBottom(); 84449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // TODO: Should we recompute the heightSpec based on the new total length? 84549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 84649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes alternativeMaxWidth = Math.max(alternativeMaxWidth, 84749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes weightedMaxWidth); 84849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 84949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 85049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // We have no limit, so make all weighted views as tall as the largest child. 85149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Children will have already been measured once. 85249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (useLargestChild && heightMode != MeasureSpec.EXACTLY) { 85349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; i++) { 85449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(i); 85549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 85649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child == null || child.getVisibility() == View.GONE) { 85749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes continue; 85849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 85949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 86049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final LinearLayoutCompat.LayoutParams lp = 86149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes (LinearLayoutCompat.LayoutParams) child.getLayoutParams(); 86249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 86349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes float childExtra = lp.weight; 86449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (childExtra > 0) { 86549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes child.measure( 86649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(), 86749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MeasureSpec.EXACTLY), 86849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MeasureSpec.makeMeasureSpec(largestChildHeight, 86949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MeasureSpec.EXACTLY)); 87049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 87149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 87249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 87349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 87449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 87549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!allFillParent && widthMode != MeasureSpec.EXACTLY) { 87649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxWidth = alternativeMaxWidth; 87749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 87849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 87949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxWidth += getPaddingLeft() + getPaddingRight(); 88049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 88149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Check against our minimum width 88249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth()); 88349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 884fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas setMeasuredDimension(View.resolveSizeAndState(maxWidth, widthMeasureSpec, childState), 88549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes heightSizeAndState); 88649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 88749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (matchWidth) { 88849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes forceUniformWidth(count, heightMeasureSpec); 88949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 89049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 89149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 89249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private void forceUniformWidth(int count, int heightMeasureSpec) { 89349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Pretend that the linear layout has an exact size. 89449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int uniformMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), 89549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MeasureSpec.EXACTLY); 89649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i< count; ++i) { 89749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(i); 89849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child.getVisibility() != GONE) { 89949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes LinearLayoutCompat.LayoutParams lp = ((LinearLayoutCompat.LayoutParams)child.getLayoutParams()); 90049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 90149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (lp.width == LayoutParams.MATCH_PARENT) { 90249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Temporarily force children to reuse their old measured height 90349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // FIXME: this may not be right for something like wrapping text? 90449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int oldHeight = lp.height; 90549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.height = child.getMeasuredHeight(); 90649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 90749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Remeasue with new dimensions 90849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes measureChildWithMargins(child, uniformMeasureSpec, 0, heightMeasureSpec, 0); 90949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.height = oldHeight; 91049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 91149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 91249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 91349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 91449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 91549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 91649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Measures the children when the orientation of this LinearLayout is set 91749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * to {@link #HORIZONTAL}. 91849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 91949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param widthMeasureSpec Horizontal space requirements as imposed by the parent. 92049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param heightMeasureSpec Vertical space requirements as imposed by the parent. 92149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 92249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #getOrientation() 92349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #setOrientation(int) 92449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #onMeasure(int, int) 92549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 92649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void measureHorizontal(int widthMeasureSpec, int heightMeasureSpec) { 92749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength = 0; 92849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int maxHeight = 0; 92949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childState = 0; 93049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int alternativeMaxHeight = 0; 93149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int weightedMaxHeight = 0; 93249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes boolean allFillParent = true; 93349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes float totalWeight = 0; 93449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 93549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int count = getVirtualChildCount(); 93649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 93749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 93849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 93949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 94049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes boolean matchHeight = false; 94149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes boolean skippedMeasure = false; 94249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 94349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mMaxAscent == null || mMaxDescent == null) { 94449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mMaxAscent = new int[VERTICAL_GRAVITY_COUNT]; 94549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mMaxDescent = new int[VERTICAL_GRAVITY_COUNT]; 94649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 94749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 94849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int[] maxAscent = mMaxAscent; 94949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int[] maxDescent = mMaxDescent; 95049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 95149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxAscent[0] = maxAscent[1] = maxAscent[2] = maxAscent[3] = -1; 95249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxDescent[0] = maxDescent[1] = maxDescent[2] = maxDescent[3] = -1; 95349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 95449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final boolean baselineAligned = mBaselineAligned; 95549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final boolean useLargestChild = mUseLargestChild; 95649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 95749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final boolean isExactly = widthMode == MeasureSpec.EXACTLY; 95849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 95949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int largestChildWidth = Integer.MIN_VALUE; 96049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 96149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // See how wide everyone is. Also remember max height. 96249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; ++i) { 96349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(i); 96449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 96549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child == null) { 96649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += measureNullChild(i); 96749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes continue; 96849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 96949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 97049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child.getVisibility() == GONE) { 97149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes i += getChildrenSkipCount(child, i); 97249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes continue; 97349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 97449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 97549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (hasDividerBeforeChildAt(i)) { 97649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += mDividerWidth; 97749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 97849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 97949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final LinearLayoutCompat.LayoutParams lp = (LinearLayoutCompat.LayoutParams) 98049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes child.getLayoutParams(); 98149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 98249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes totalWeight += lp.weight; 98349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 98449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (widthMode == MeasureSpec.EXACTLY && lp.width == 0 && lp.weight > 0) { 98549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Optimization: don't bother measuring children who are going to use 98649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // leftover space. These views will get measured again down below if 98749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // there is any leftover space. 98849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (isExactly) { 98949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += lp.leftMargin + lp.rightMargin; 99049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 99149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int totalLength = mTotalLength; 99249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength = Math.max(totalLength, totalLength + 99349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.leftMargin + lp.rightMargin); 99449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 99549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 99649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Baseline alignment requires to measure widgets to obtain the 99749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // baseline offset (in particular for TextViews). The following 99849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // defeats the optimization mentioned above. Allow the child to 99949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // use as much space as it wants because we can shrink things 100049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // later (and re-measure). 100149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (baselineAligned) { 100249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int freeSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 100349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes child.measure(freeSpec, freeSpec); 100449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 100549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes skippedMeasure = true; 100649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 100749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 100849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int oldWidth = Integer.MIN_VALUE; 100949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 101049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (lp.width == 0 && lp.weight > 0) { 101149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // widthMode is either UNSPECIFIED or AT_MOST, and this 101249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // child 101349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // wanted to stretch to fill available space. Translate that to 101449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // WRAP_CONTENT so that it does not end up with a width of 0 101549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes oldWidth = 0; 101649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.width = LayoutParams.WRAP_CONTENT; 101749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 101849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 101949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Determine how big this child would like to be. If this or 102049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // previous children have given a weight, then we allow it to 102149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // use all available space (and we will shrink things later 102249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // if needed). 102349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes measureChildBeforeLayout(child, i, widthMeasureSpec, 102449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes totalWeight == 0 ? mTotalLength : 0, 102549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes heightMeasureSpec, 0); 102649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 102749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (oldWidth != Integer.MIN_VALUE) { 102849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.width = oldWidth; 102949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 103049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 103149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int childWidth = child.getMeasuredWidth(); 103249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (isExactly) { 103349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += childWidth + lp.leftMargin + lp.rightMargin + 103449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes getNextLocationOffset(child); 103549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 103649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int totalLength = mTotalLength; 103749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength = Math.max(totalLength, totalLength + childWidth + lp.leftMargin + 103849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.rightMargin + getNextLocationOffset(child)); 103949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 104049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 104149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (useLargestChild) { 104249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes largestChildWidth = Math.max(childWidth, largestChildWidth); 104349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 104449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 104549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 104649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes boolean matchHeightLocally = false; 104749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (heightMode != MeasureSpec.EXACTLY && lp.height == LayoutParams.MATCH_PARENT) { 104849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // The height of the linear layout will scale, and at least one 104949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // child said it wanted to match our height. Set a flag indicating that 105049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // we need to remeasure at least that view when we know our height. 105149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes matchHeight = true; 105249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes matchHeightLocally = true; 105349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 105449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 105549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int margin = lp.topMargin + lp.bottomMargin; 105649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int childHeight = child.getMeasuredHeight() + margin; 105749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childState = ViewUtils.combineMeasuredStates(childState, 1058fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas child.getMeasuredState()); 105949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 106049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (baselineAligned) { 106149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int childBaseline = child.getBaseline(); 106249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (childBaseline != -1) { 106349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Translates the child's vertical gravity into an index 106449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // in the range 0..VERTICAL_GRAVITY_COUNT 106549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int gravity = (lp.gravity < 0 ? mGravity : lp.gravity) 106649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes & Gravity.VERTICAL_GRAVITY_MASK; 106749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int index = ((gravity >> Gravity.AXIS_Y_SHIFT) 106849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes & ~Gravity.AXIS_SPECIFIED) >> 1; 106949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 107049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxAscent[index] = Math.max(maxAscent[index], childBaseline); 107149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxDescent[index] = Math.max(maxDescent[index], childHeight - childBaseline); 107249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 107349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 107449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 107549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight = Math.max(maxHeight, childHeight); 107649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 107749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes allFillParent = allFillParent && lp.height == LayoutParams.MATCH_PARENT; 107849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (lp.weight > 0) { 107949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /* 108049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Heights of weighted Views are bogus if we end up 108149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * remeasuring, so keep them separate. 108249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 108349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes weightedMaxHeight = Math.max(weightedMaxHeight, 108449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes matchHeightLocally ? margin : childHeight); 108549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 108649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes alternativeMaxHeight = Math.max(alternativeMaxHeight, 108749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes matchHeightLocally ? margin : childHeight); 108849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 108949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 109049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes i += getChildrenSkipCount(child, i); 109149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 109249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 109349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mTotalLength > 0 && hasDividerBeforeChildAt(count)) { 109449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += mDividerWidth; 109549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 109649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 109749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Check mMaxAscent[INDEX_TOP] first because it maps to Gravity.TOP, 109849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // the most common case 109949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (maxAscent[INDEX_TOP] != -1 || 110049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxAscent[INDEX_CENTER_VERTICAL] != -1 || 110149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxAscent[INDEX_BOTTOM] != -1 || 110249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxAscent[INDEX_FILL] != -1) { 110349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int ascent = Math.max(maxAscent[INDEX_FILL], 110449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes Math.max(maxAscent[INDEX_CENTER_VERTICAL], 110549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes Math.max(maxAscent[INDEX_TOP], maxAscent[INDEX_BOTTOM]))); 110649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int descent = Math.max(maxDescent[INDEX_FILL], 110749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes Math.max(maxDescent[INDEX_CENTER_VERTICAL], 110849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes Math.max(maxDescent[INDEX_TOP], maxDescent[INDEX_BOTTOM]))); 110949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight = Math.max(maxHeight, ascent + descent); 111049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 111149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 111249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (useLargestChild && 111349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.UNSPECIFIED)) { 111449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength = 0; 111549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 111649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; ++i) { 111749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(i); 111849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 111949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child == null) { 112049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += measureNullChild(i); 112149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes continue; 112249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 112349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 112449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child.getVisibility() == GONE) { 112549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes i += getChildrenSkipCount(child, i); 112649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes continue; 112749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 112849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 112949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final LinearLayoutCompat.LayoutParams lp = (LinearLayoutCompat.LayoutParams) 113049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes child.getLayoutParams(); 113149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (isExactly) { 113249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += largestChildWidth + lp.leftMargin + lp.rightMargin + 113349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes getNextLocationOffset(child); 113449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 113549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int totalLength = mTotalLength; 113649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength = Math.max(totalLength, totalLength + largestChildWidth + 113749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.leftMargin + lp.rightMargin + getNextLocationOffset(child)); 113849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 113949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 114049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 114149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 114249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Add in our padding 114349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += getPaddingLeft() + getPaddingRight(); 114449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 114549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int widthSize = mTotalLength; 114649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 114749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Check against our minimum width 114849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes widthSize = Math.max(widthSize, getSuggestedMinimumWidth()); 114949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 115049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Reconcile our calculated size with the widthMeasureSpec 1151fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas int widthSizeAndState = View.resolveSizeAndState(widthSize, widthMeasureSpec, 0); 1152fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas widthSize = widthSizeAndState & View.MEASURED_SIZE_MASK; 115349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 115449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Either expand children with weight to take up available space or 115549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // shrink them if they extend beyond our current bounds. If we skipped 115649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // measurement on any children, we need to measure them now. 115749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int delta = widthSize - mTotalLength; 1158ad1b0e82100ee31e70040d77bfa4d847b2bf0864Aurimas Liutikas if (skippedMeasure || (delta != 0 && totalWeight > 0.0f)) { 115949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight; 116049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 116149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxAscent[0] = maxAscent[1] = maxAscent[2] = maxAscent[3] = -1; 116249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxDescent[0] = maxDescent[1] = maxDescent[2] = maxDescent[3] = -1; 116349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight = -1; 116449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 116549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength = 0; 116649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 116749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; ++i) { 116849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(i); 116949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 117049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child == null || child.getVisibility() == View.GONE) { 117149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes continue; 117249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 117349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 117449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final LinearLayoutCompat.LayoutParams lp = 117549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes (LinearLayoutCompat.LayoutParams) child.getLayoutParams(); 117649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 117749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes float childExtra = lp.weight; 117849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (childExtra > 0) { 117949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Child said it could absorb extra space -- give him his share 118049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int share = (int) (childExtra * delta / weightSum); 118149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes weightSum -= childExtra; 118249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes delta -= share; 118349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 118449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int childHeightMeasureSpec = getChildMeasureSpec( 118549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes heightMeasureSpec, 118649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin, 118749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.height); 118849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 118949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // TODO: Use a field like lp.isMeasured to figure out if this 119049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // child has been previously measured 119149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if ((lp.width != 0) || (widthMode != MeasureSpec.EXACTLY)) { 119249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // child was measured once already above ... base new measurement 119349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // on stored values 119449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childWidth = child.getMeasuredWidth() + share; 119549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (childWidth < 0) { 119649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childWidth = 0; 119749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 119849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 119949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes child.measure( 120049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY), 120149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childHeightMeasureSpec); 120249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 120349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // child was skipped in the loop above. Measure for this first time here 120449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes child.measure(MeasureSpec.makeMeasureSpec( 120549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes share > 0 ? share : 0, MeasureSpec.EXACTLY), 120649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childHeightMeasureSpec); 120749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 120849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 120949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Child may now not fit in horizontal dimension. 1210fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas childState = View.combineMeasuredStates(childState, 1211fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas child.getMeasuredState() & View.MEASURED_STATE_MASK); 121249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 121349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 121449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (isExactly) { 121549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin + 121649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes getNextLocationOffset(child); 121749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 121849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int totalLength = mTotalLength; 121949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength = Math.max(totalLength, totalLength + child.getMeasuredWidth() + 122049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.leftMargin + lp.rightMargin + getNextLocationOffset(child)); 122149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 122249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 122349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes boolean matchHeightLocally = heightMode != MeasureSpec.EXACTLY && 122449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.height == LayoutParams.MATCH_PARENT; 122549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 122649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int margin = lp.topMargin + lp .bottomMargin; 122749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childHeight = child.getMeasuredHeight() + margin; 122849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight = Math.max(maxHeight, childHeight); 122949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes alternativeMaxHeight = Math.max(alternativeMaxHeight, 123049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes matchHeightLocally ? margin : childHeight); 123149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 123249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes allFillParent = allFillParent && lp.height == LayoutParams.MATCH_PARENT; 123349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 123449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (baselineAligned) { 123549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int childBaseline = child.getBaseline(); 123649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (childBaseline != -1) { 123749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Translates the child's vertical gravity into an index in the range 0..2 123849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int gravity = (lp.gravity < 0 ? mGravity : lp.gravity) 123949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes & Gravity.VERTICAL_GRAVITY_MASK; 124049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int index = ((gravity >> Gravity.AXIS_Y_SHIFT) 124149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes & ~Gravity.AXIS_SPECIFIED) >> 1; 124249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 124349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxAscent[index] = Math.max(maxAscent[index], childBaseline); 124449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxDescent[index] = Math.max(maxDescent[index], 124549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childHeight - childBaseline); 124649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 124749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 124849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 124949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 125049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Add in our padding 125149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mTotalLength += getPaddingLeft() + getPaddingRight(); 125249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // TODO: Should we update widthSize with the new total length? 125349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 125449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Check mMaxAscent[INDEX_TOP] first because it maps to Gravity.TOP, 125549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // the most common case 125649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (maxAscent[INDEX_TOP] != -1 || 125749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxAscent[INDEX_CENTER_VERTICAL] != -1 || 125849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxAscent[INDEX_BOTTOM] != -1 || 125949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxAscent[INDEX_FILL] != -1) { 126049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int ascent = Math.max(maxAscent[INDEX_FILL], 126149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes Math.max(maxAscent[INDEX_CENTER_VERTICAL], 126249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes Math.max(maxAscent[INDEX_TOP], maxAscent[INDEX_BOTTOM]))); 126349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int descent = Math.max(maxDescent[INDEX_FILL], 126449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes Math.max(maxDescent[INDEX_CENTER_VERTICAL], 126549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes Math.max(maxDescent[INDEX_TOP], maxDescent[INDEX_BOTTOM]))); 126649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight = Math.max(maxHeight, ascent + descent); 126749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 126849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 126949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes alternativeMaxHeight = Math.max(alternativeMaxHeight, weightedMaxHeight); 127049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 127149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // We have no limit, so make all weighted views as wide as the largest child. 127249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Children will have already been measured once. 127349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (useLargestChild && widthMode != MeasureSpec.EXACTLY) { 127449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; i++) { 127549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(i); 127649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 127749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child == null || child.getVisibility() == View.GONE) { 127849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes continue; 127949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 128049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 128149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final LinearLayoutCompat.LayoutParams lp = 128249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes (LinearLayoutCompat.LayoutParams) child.getLayoutParams(); 128349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 128449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes float childExtra = lp.weight; 128549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (childExtra > 0) { 128649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes child.measure( 128749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MeasureSpec.makeMeasureSpec(largestChildWidth, MeasureSpec.EXACTLY), 128849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(), 128949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MeasureSpec.EXACTLY)); 129049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 129149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 129249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 129349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 129449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 129549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (!allFillParent && heightMode != MeasureSpec.EXACTLY) { 129649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight = alternativeMaxHeight; 129749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 129849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 129949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight += getPaddingTop() + getPaddingBottom(); 130049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 130149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Check against our minimum height 130249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight()); 130349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 1304fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas setMeasuredDimension(widthSizeAndState | (childState & View.MEASURED_STATE_MASK), 1305fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas View.resolveSizeAndState(maxHeight, heightMeasureSpec, 1306fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas (childState << View.MEASURED_HEIGHT_STATE_SHIFT))); 130749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 130849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (matchHeight) { 130949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes forceUniformHeight(count, widthMeasureSpec); 131049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 131149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 131249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 131349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private void forceUniformHeight(int count, int widthMeasureSpec) { 131449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Pretend that the linear layout has an exact size. This is the measured height of 131549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // ourselves. The measured height should be the max height of the children, changed 131649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // to accommodate the heightMeasureSpec from the parent 131749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int uniformMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), 131849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes MeasureSpec.EXACTLY); 131949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; ++i) { 132049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(i); 132149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child.getVisibility() != GONE) { 132249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes LinearLayoutCompat.LayoutParams lp = (LinearLayoutCompat.LayoutParams) child.getLayoutParams(); 132349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 132449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (lp.height == LayoutParams.MATCH_PARENT) { 132549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Temporarily force children to reuse their old measured width 132649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // FIXME: this may not be right for something like wrapping text? 132749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int oldWidth = lp.width; 132849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.width = child.getMeasuredWidth(); 132949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 133049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Remeasure with new dimensions 133149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes measureChildWithMargins(child, widthMeasureSpec, 0, uniformMeasureSpec, 0); 133249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes lp.width = oldWidth; 133349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 133449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 133549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 133649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 133749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 133849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 133949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * <p>Returns the number of children to skip after measuring/laying out 134049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * the specified child.</p> 134149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 134249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param child the child after which we want to skip children 134349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param index the index of the child after which we want to skip children 134449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return the number of children to skip, 0 by default 134549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 134649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int getChildrenSkipCount(View child, int index) { 134749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return 0; 134849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 134949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 135049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 135149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * <p>Returns the size (width or height) that should be occupied by a null 135249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * child.</p> 135349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 135449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param childIndex the index of the null child 135549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return the width or height of the child depending on the orientation 135649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 135749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int measureNullChild(int childIndex) { 135849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return 0; 135949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 136049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 136149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 136249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * <p>Measure the child according to the parent's measure specs. This 1363c9a859537b0871f84afeeb706a5b425fe3f2b4ddAurimas Liutikas * method should be overridden by subclasses to force the sizing of 136449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * children. This method is called by {@link #measureVertical(int, int)} and 136549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * {@link #measureHorizontal(int, int)}.</p> 136649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 136749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param child the child to measure 136849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param childIndex the index of the child in this view 136949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param widthMeasureSpec horizontal space requirements as imposed by the parent 137049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param totalWidth extra space that has been used up by the parent horizontally 137149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param heightMeasureSpec vertical space requirements as imposed by the parent 137249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param totalHeight extra space that has been used up by the parent vertically 137349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 137449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void measureChildBeforeLayout(View child, int childIndex, 137549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int widthMeasureSpec, int totalWidth, int heightMeasureSpec, 137649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int totalHeight) { 137749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes measureChildWithMargins(child, widthMeasureSpec, totalWidth, 137849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes heightMeasureSpec, totalHeight); 137949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 138049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 138149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 138249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * <p>Return the location offset of the specified child. This can be used 138349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * by subclasses to change the location of a given widget.</p> 138449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 138549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param child the child for which to obtain the location offset 138649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return the location offset in pixels 138749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 138849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int getLocationOffset(View child) { 138949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return 0; 139049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 139149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 139249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 139349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * <p>Return the size offset of the next sibling of the specified child. 139449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * This can be used by subclasses to change the location of the widget 139549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * following <code>child</code>.</p> 139649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 139749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param child the child whose next sibling will be moved 139849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return the location offset of the next child in pixels 139949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 140049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int getNextLocationOffset(View child) { 140149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return 0; 140249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 140349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 140449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 140549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected void onLayout(boolean changed, int l, int t, int r, int b) { 140649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mOrientation == VERTICAL) { 140749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes layoutVertical(l, t, r, b); 140849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else { 140949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes layoutHorizontal(l, t, r, b); 141049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 141149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 141249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 141349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 141449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Position the children during a layout pass if the orientation of this 141549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * LinearLayout is set to {@link #VERTICAL}. 141649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 141749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #getOrientation() 141849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #setOrientation(int) 141949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #onLayout(boolean, int, int, int, int) 142049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param left 142149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param top 142249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param right 142349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param bottom 142449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 142549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void layoutVertical(int left, int top, int right, int bottom) { 142649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int paddingLeft = getPaddingLeft(); 142749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 142849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childTop; 142949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childLeft; 143049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 143149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Where right end of child should go 143249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int width = right - left; 143349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childRight = width - getPaddingRight(); 143449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 143549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Space available for child 143649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childSpace = width - paddingLeft - getPaddingRight(); 143749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 143849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int count = getVirtualChildCount(); 143949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 144049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int majorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK; 144149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int minorGravity = mGravity & GravityCompat.RELATIVE_HORIZONTAL_GRAVITY_MASK; 144249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 144349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes switch (majorGravity) { 144449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Gravity.BOTTOM: 144549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // mTotalLength contains the padding already 144649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop = getPaddingTop() + bottom - top - mTotalLength; 144749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 144849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 144949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // mTotalLength contains the padding already 145049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Gravity.CENTER_VERTICAL: 145149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop = getPaddingTop() + (bottom - top - mTotalLength) / 2; 145249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 145349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 145449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Gravity.TOP: 145549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes default: 145649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop = getPaddingTop(); 145749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 145849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 145949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 146049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; i++) { 146149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(i); 146249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child == null) { 146349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop += measureNullChild(i); 146449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else if (child.getVisibility() != GONE) { 146549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int childWidth = child.getMeasuredWidth(); 146649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int childHeight = child.getMeasuredHeight(); 146749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 146849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final LinearLayoutCompat.LayoutParams lp = 146949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes (LinearLayoutCompat.LayoutParams) child.getLayoutParams(); 147049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 147149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int gravity = lp.gravity; 147249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (gravity < 0) { 147349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes gravity = minorGravity; 147449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 147549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int layoutDirection = ViewCompat.getLayoutDirection(this); 147649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int absoluteGravity = GravityCompat.getAbsoluteGravity(gravity, 147749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes layoutDirection); 147849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { 147949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Gravity.CENTER_HORIZONTAL: 148049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childLeft = paddingLeft + ((childSpace - childWidth) / 2) 148149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes + lp.leftMargin - lp.rightMargin; 148249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 148349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 148449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Gravity.RIGHT: 148549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childLeft = childRight - childWidth - lp.rightMargin; 148649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 148749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 148849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Gravity.LEFT: 148949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes default: 149049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childLeft = paddingLeft + lp.leftMargin; 149149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 149249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 149349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 149449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (hasDividerBeforeChildAt(i)) { 149549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop += mDividerHeight; 149649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 149749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 149849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop += lp.topMargin; 149949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setChildFrame(child, childLeft, childTop + getLocationOffset(child), 150049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childWidth, childHeight); 150149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop += childHeight + lp.bottomMargin + getNextLocationOffset(child); 150249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 150349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes i += getChildrenSkipCount(child, i); 150449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 150549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 150649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 150749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 150849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 150949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Position the children during a layout pass if the orientation of this 151049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * LinearLayout is set to {@link #HORIZONTAL}. 151149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 151249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #getOrientation() 151349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #setOrientation(int) 151449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see #onLayout(boolean, int, int, int, int) 151549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param left 151649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param top 151749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param right 151849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param bottom 151949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 152049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes void layoutHorizontal(int left, int top, int right, int bottom) { 152149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final boolean isLayoutRtl = ViewUtils.isLayoutRtl(this); 152249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int paddingTop = getPaddingTop(); 152349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 152449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childTop; 152549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childLeft; 152649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 152749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Where bottom of child should go 152849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int height = bottom - top; 152949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childBottom = height - getPaddingBottom(); 153049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 153149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Space available for child 153249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childSpace = height - paddingTop - getPaddingBottom(); 153349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 153449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int count = getVirtualChildCount(); 153549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 153649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int majorGravity = mGravity & GravityCompat.RELATIVE_HORIZONTAL_GRAVITY_MASK; 153749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int minorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK; 153849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 153949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final boolean baselineAligned = mBaselineAligned; 154049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 154149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int[] maxAscent = mMaxAscent; 154249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int[] maxDescent = mMaxDescent; 154349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 154449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int layoutDirection = ViewCompat.getLayoutDirection(this); 154549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes switch (GravityCompat.getAbsoluteGravity(majorGravity, layoutDirection)) { 154649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Gravity.RIGHT: 154749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // mTotalLength contains the padding already 154849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childLeft = getPaddingLeft() + right - left - mTotalLength; 154949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 155049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 155149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Gravity.CENTER_HORIZONTAL: 155249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // mTotalLength contains the padding already 155349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childLeft = getPaddingLeft() + (right - left - mTotalLength) / 2; 155449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 155549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 155649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Gravity.LEFT: 155749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes default: 155849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childLeft = getPaddingLeft(); 155949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 156049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 156149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 156249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int start = 0; 156349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int dir = 1; 156449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes //In case of RTL, start drawing from the last child. 156549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (isLayoutRtl) { 156649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes start = count - 1; 156749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes dir = -1; 156849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 156949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 157049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes for (int i = 0; i < count; i++) { 157149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childIndex = start + dir * i; 157249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final View child = getVirtualChildAt(childIndex); 157349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 157449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (child == null) { 157549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childLeft += measureNullChild(childIndex); 157649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else if (child.getVisibility() != GONE) { 157749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int childWidth = child.getMeasuredWidth(); 157849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int childHeight = child.getMeasuredHeight(); 157949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int childBaseline = -1; 158049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 158149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final LinearLayoutCompat.LayoutParams lp = 158249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes (LinearLayoutCompat.LayoutParams) child.getLayoutParams(); 158349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 158449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (baselineAligned && lp.height != LayoutParams.MATCH_PARENT) { 158549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childBaseline = child.getBaseline(); 158649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 158749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 158849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int gravity = lp.gravity; 158949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (gravity < 0) { 159049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes gravity = minorGravity; 159149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 159249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 159349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) { 159449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Gravity.TOP: 159549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop = paddingTop + lp.topMargin; 159649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (childBaseline != -1) { 159749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop += maxAscent[INDEX_TOP] - childBaseline; 159849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 159949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 160049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 160149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Gravity.CENTER_VERTICAL: 160249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Removed support for baseline alignment when layout_gravity or 160349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // gravity == center_vertical. See bug #1038483. 160449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Keep the code around if we need to re-enable this feature 160549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // if (childBaseline != -1) { 160649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // // Align baselines vertically only if the child is smaller than us 160749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // if (childSpace - childHeight > 0) { 160849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // childTop = paddingTop + (childSpace / 2) - childBaseline; 160949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // } else { 161049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // childTop = paddingTop + (childSpace - childHeight) / 2; 161149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // } 161249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // } else { 161349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop = paddingTop + ((childSpace - childHeight) / 2) 161449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes + lp.topMargin - lp.bottomMargin; 161549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 161649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 161749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes case Gravity.BOTTOM: 161849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop = childBottom - childHeight - lp.bottomMargin; 161949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (childBaseline != -1) { 162049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes int descent = child.getMeasuredHeight() - childBaseline; 162149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop -= (maxDescent[INDEX_BOTTOM] - descent); 162249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 162349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 162449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes default: 162549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childTop = paddingTop; 162649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes break; 162749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 162849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 162949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (hasDividerBeforeChildAt(childIndex)) { 163049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childLeft += mDividerWidth; 163149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 163249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 163349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childLeft += lp.leftMargin; 163449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes setChildFrame(child, childLeft + getLocationOffset(child), childTop, 163549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childWidth, childHeight); 163649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes childLeft += childWidth + lp.rightMargin + 163749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes getNextLocationOffset(child); 163849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 163949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes i += getChildrenSkipCount(child, childIndex); 164049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 164149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 164249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 164349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 164449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private void setChildFrame(View child, int left, int top, int width, int height) { 164549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes child.layout(left, top, left + width, top + height); 164649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 164749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 164849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 164949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Should the layout be a column or a row. 165049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param orientation Pass {@link #HORIZONTAL} or {@link #VERTICAL}. Default 165149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * value is {@link #HORIZONTAL}. 165249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 165349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setOrientation(@OrientationMode int orientation) { 165449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mOrientation != orientation) { 165549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mOrientation = orientation; 165649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes requestLayout(); 165749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 165849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 165949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 166049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 166149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Returns the current orientation. 166249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 166349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @return either {@link #HORIZONTAL} or {@link #VERTICAL} 166449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 166549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @OrientationMode 166649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public int getOrientation() { 166749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return mOrientation; 166849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 166949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 167049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 167149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Describes how the child views are positioned. Defaults to GRAVITY_TOP. If 167249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * this layout has a VERTICAL orientation, this controls where all the child 167349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * views are placed if there is extra vertical space. If this layout has a 167449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * HORIZONTAL orientation, this controls the alignment of the children. 167549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 167649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param gravity See {@link android.view.Gravity} 167749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 167849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setGravity(int gravity) { 167949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mGravity != gravity) { 168049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if ((gravity & GravityCompat.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) { 168149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes gravity |= GravityCompat.START; 168249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 168349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 168449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) { 168549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes gravity |= Gravity.TOP; 168649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 168749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 168849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mGravity = gravity; 168949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes requestLayout(); 169049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 169149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 169249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 16932c96011dee46e09d6ab766a42a98b299927d633bChris Banes /** 16942c96011dee46e09d6ab766a42a98b299927d633bChris Banes * Returns the current gravity. See {@link android.view.Gravity} 16952c96011dee46e09d6ab766a42a98b299927d633bChris Banes * 16962c96011dee46e09d6ab766a42a98b299927d633bChris Banes * @return the current gravity. 16972c96011dee46e09d6ab766a42a98b299927d633bChris Banes * @see #setGravity 16982c96011dee46e09d6ab766a42a98b299927d633bChris Banes */ 16992c96011dee46e09d6ab766a42a98b299927d633bChris Banes public int getGravity() { 17002c96011dee46e09d6ab766a42a98b299927d633bChris Banes return mGravity; 17012c96011dee46e09d6ab766a42a98b299927d633bChris Banes } 17022c96011dee46e09d6ab766a42a98b299927d633bChris Banes 170349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setHorizontalGravity(int horizontalGravity) { 170449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int gravity = horizontalGravity & GravityCompat.RELATIVE_HORIZONTAL_GRAVITY_MASK; 170549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if ((mGravity & GravityCompat.RELATIVE_HORIZONTAL_GRAVITY_MASK) != gravity) { 170649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mGravity = (mGravity & ~GravityCompat.RELATIVE_HORIZONTAL_GRAVITY_MASK) | gravity; 170749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes requestLayout(); 170849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 170949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 171049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 171149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void setVerticalGravity(int verticalGravity) { 171249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes final int gravity = verticalGravity & Gravity.VERTICAL_GRAVITY_MASK; 171349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != gravity) { 171449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mGravity = (mGravity & ~Gravity.VERTICAL_GRAVITY_MASK) | gravity; 171549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes requestLayout(); 171649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 171749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 171849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 171949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 172049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams generateLayoutParams(AttributeSet attrs) { 172149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return new LinearLayoutCompat.LayoutParams(getContext(), attrs); 172249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 172349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 172449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 172549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Returns a set of layout parameters with a width of 172649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT} 172749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * and a height of {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} 172849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * when the layout's orientation is {@link #VERTICAL}. When the orientation is 172949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * {@link #HORIZONTAL}, the width is set to {@link LayoutParams#WRAP_CONTENT} 173049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * and the height to {@link LayoutParams#WRAP_CONTENT}. 173149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 173249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 173349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected LayoutParams generateDefaultLayoutParams() { 173449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mOrientation == HORIZONTAL) { 173549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 173649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } else if (mOrientation == VERTICAL) { 173749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); 173849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 173949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return null; 174049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 174149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 174249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 174349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 174449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return new LayoutParams(p); 174549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 174649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 174749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 174849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes // Override to allow type-checking of LayoutParams. 174949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 175049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 175149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return p instanceof LinearLayoutCompat.LayoutParams; 175249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 175349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 1754e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 175549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 175649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (Build.VERSION.SDK_INT >= 14) { 175749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super.onInitializeAccessibilityEvent(event); 175849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes event.setClassName(LinearLayoutCompat.class.getName()); 175949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 176049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 176149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 1762e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas @Override 176349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 176449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (Build.VERSION.SDK_INT >= 14) { 176549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super.onInitializeAccessibilityNodeInfo(info); 176649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes info.setClassName(LinearLayoutCompat.class.getName()); 176749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 176849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 176949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 177049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 177149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Per-child layout information associated with ViewLinearLayout. 177249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 177349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public static class LayoutParams extends ViewGroup.MarginLayoutParams { 177449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 177549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Indicates how much of the extra space in the LinearLayout will be 177649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * allocated to the view associated with these LayoutParams. Specify 177749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 0 if the view should not be stretched. Otherwise the extra pixels 177849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * will be pro-rated among all views whose weight is greater than 0. 177949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 178049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public float weight; 178149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 178249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 178349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Gravity for the view associated with these LayoutParams. 178449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 178549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @see android.view.Gravity 178649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 178749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public int gravity = -1; 178849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 178949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 179049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * {@inheritDoc} 179149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 179249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams(Context c, AttributeSet attrs) { 179349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(c, attrs); 179449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes TypedArray a = 179549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes c.obtainStyledAttributes(attrs, R.styleable.LinearLayoutCompat_Layout); 179649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 179749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes weight = a.getFloat(R.styleable.LinearLayoutCompat_Layout_android_layout_weight, 0); 179849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes gravity = a.getInt(R.styleable.LinearLayoutCompat_Layout_android_layout_gravity, -1); 179949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 180049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes a.recycle(); 180149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 180249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 180349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 180449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * {@inheritDoc} 180549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 180649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams(int width, int height) { 180749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(width, height); 180849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes weight = 0; 180949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 181049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 181149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 181249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Creates a new set of layout parameters with the specified width, height 181349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * and weight. 181449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 181549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param width the width, either {@link #MATCH_PARENT}, 181649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * {@link #WRAP_CONTENT} or a fixed size in pixels 181749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param height the height, either {@link #MATCH_PARENT}, 181849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * {@link #WRAP_CONTENT} or a fixed size in pixels 181949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param weight the weight 182049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 182149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams(int width, int height, float weight) { 182249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(width, height); 182349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes this.weight = weight; 182449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 182549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 182649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 182749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * {@inheritDoc} 182849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 182949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams(ViewGroup.LayoutParams p) { 183049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(p); 183149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 183249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 183349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 183449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * {@inheritDoc} 183549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 183649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams(ViewGroup.MarginLayoutParams source) { 183749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(source); 183849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 183949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 184049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes /** 184149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Copy constructor. Clones the width, height, margin values, weight, 184249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * and gravity of the source. 184349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * 184449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @param source The layout params to copy from. 184549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */ 184649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes public LayoutParams(LayoutParams source) { 184749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super(source); 184849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 184949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes this.weight = source.weight; 185049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes this.gravity = source.gravity; 185149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 185249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 18536da3e2ee07ff8acd7de4ed810eafeb70a8d4027dChris Banes} 1854