diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java index fa84407c5c4db..7314ad83bd0cf 100644 --- a/core/java/android/widget/LinearLayout.java +++ b/core/java/android/widget/LinearLayout.java @@ -732,6 +732,10 @@ public class LinearLayout extends ViewGroup { * @hide Pending API consideration. Currently only used internally by the system. */ protected boolean hasDividerBeforeChildAt(int childIndex) { + if (mShowDividers == SHOW_DIVIDER_NONE) { + // Short-circuit to save iteration over child views. + return false; + } if (childIndex == getVirtualChildCount()) { // Check whether the end divider should draw. return (mShowDividers & SHOW_DIVIDER_END) != 0; @@ -745,6 +749,24 @@ public class LinearLayout extends ViewGroup { } } + /** + * Determines whether or not there's a divider after a specified child index. + * + * @param childIndex Index of child to check for following divider + * @return true if there should be a divider after the child at childIndex + */ + private boolean hasDividerAfterChildAt(int childIndex) { + if (mShowDividers == SHOW_DIVIDER_NONE) { + // Short-circuit to save iteration over child views. + return false; + } + if (allViewsAreGoneAfter(childIndex)) { + // This is the last view that's not gone, check if end divider is enabled. + return (mShowDividers & SHOW_DIVIDER_END) != 0; + } + return (mShowDividers & SHOW_DIVIDER_MIDDLE) != 0; + } + /** * Checks whether all (virtual) child views before the given index are gone. */ @@ -758,6 +780,20 @@ public class LinearLayout extends ViewGroup { return true; } + /** + * Checks whether all (virtual) child views after the given index are gone. + */ + private boolean allViewsAreGoneAfter(int childIndex) { + final int count = getVirtualChildCount(); + for (int i = childIndex + 1; i < count; i++) { + final View child = getVirtualChildAt(i); + if (child != null && child.getVisibility() != GONE) { + return false; + } + } + return true; + } + /** * Measures the children when the orientation of this LinearLayout is set * to {@link #VERTICAL}. @@ -1295,6 +1331,7 @@ public class LinearLayout extends ViewGroup { if (useLargestChild && (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.UNSPECIFIED)) { mTotalLength = 0; + nonSkippedChildCount = 0; for (int i = 0; i < count; ++i) { final View child = getVirtualChildAt(i); @@ -1308,6 +1345,11 @@ public class LinearLayout extends ViewGroup { continue; } + nonSkippedChildCount++; + if (hasDividerBeforeChildAt(i)) { + mTotalLength += mDividerWidth; + } + final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams(); if (isExactly) { @@ -1319,6 +1361,10 @@ public class LinearLayout extends ViewGroup { lp.leftMargin + lp.rightMargin + getNextLocationOffset(child)); } } + + if (nonSkippedChildCount > 0 && hasDividerBeforeChildAt(count)) { + mTotalLength += mDividerWidth; + } } // Add in our padding @@ -1347,6 +1393,7 @@ public class LinearLayout extends ViewGroup { maxHeight = -1; mTotalLength = 0; + nonSkippedChildCount = 0; for (int i = 0; i < count; ++i) { final View child = getVirtualChildAt(i); @@ -1354,6 +1401,11 @@ public class LinearLayout extends ViewGroup { continue; } + nonSkippedChildCount++; + if (hasDividerBeforeChildAt(i)) { + mTotalLength += mDividerWidth; + } + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); final float childWeight = lp.weight; if (childWeight > 0) { @@ -1423,6 +1475,10 @@ public class LinearLayout extends ViewGroup { } } + if (nonSkippedChildCount > 0 && hasDividerBeforeChildAt(count)) { + mTotalLength += mDividerWidth; + } + // Add in our padding mTotalLength += mPaddingLeft + mPaddingRight; // TODO: Should we update widthSize with the new total length? @@ -1810,7 +1866,13 @@ public class LinearLayout extends ViewGroup { break; } - if (hasDividerBeforeChildAt(childIndex)) { + if (isLayoutRtl) { + // Because rtl rendering occurs in the reverse direction, we need to check + // after the child rather than before (since after=left in this context) + if (hasDividerAfterChildAt(childIndex)) { + childLeft += mDividerWidth; + } + } else if (hasDividerBeforeChildAt(childIndex)) { childLeft += mDividerWidth; }