From aece3136fb8a28613f600fb8786107c57c10ffb4 Mon Sep 17 00:00:00 2001 From: Takeshi Hagikura Date: Wed, 14 Jun 2017 17:17:22 +0900 Subject: [PATCH] Fixes the case where the first view's visibility is gone and the second view is in the second line. (#300) In that case, the position of the second view is misplaced. Fixes #283 --- .../flexbox/test/FlexboxAndroidTest.java | 30 +++++++++++ ...first_view_gone_first_line_single_item.xml | 53 +++++++++++++++++++ .../google/android/flexbox/FlexboxLayout.java | 24 +++------ 3 files changed, 91 insertions(+), 16 deletions(-) create mode 100644 flexbox/src/androidTest/res/layout/activity_first_view_gone_first_line_single_item.xml diff --git a/flexbox/src/androidTest/java/com/google/android/flexbox/test/FlexboxAndroidTest.java b/flexbox/src/androidTest/java/com/google/android/flexbox/test/FlexboxAndroidTest.java index 31f0b4ea..ea4aeca4 100644 --- a/flexbox/src/androidTest/java/com/google/android/flexbox/test/FlexboxAndroidTest.java +++ b/flexbox/src/androidTest/java/com/google/android/flexbox/test/FlexboxAndroidTest.java @@ -3895,6 +3895,36 @@ public void testChildNeedsRemeasure_column() throws Throwable { onView(withId(R.id.text3)).check(isBottomAlignedWith(withId(R.id.flexbox_layout))); } + @Test + @FlakyTest + public void testFirstViewGone_firstLineSingleItem_row() throws Throwable { + // This test verifies the case where the first view's visibility is gone and the second + // view is in the next flex line. In that case, the second view's position is misplaced. + // https://github.com/google/flexbox-layout/issues/283 + createFlexboxLayout(R.layout.activity_first_view_gone_first_line_single_item); + onView(withId(R.id.text2)).check(isTopAlignedWith(withId(R.id.flexbox_layout))); + onView(withId(R.id.text2)).check(isLeftAlignedWith(withId(R.id.flexbox_layout))); + onView(withId(R.id.text3)).check(isLeftAlignedWith(withId(R.id.flexbox_layout))); + } + + @Test + @FlakyTest + public void testFirstViewGone_firstLineSingleItem_column() throws Throwable { + // This test verifies the case where the first view's visibility is gone and the second + // view is in the next flex line. In that case, the second view's position is misplaced. + // https://github.com/google/flexbox-layout/issues/283 + createFlexboxLayout(R.layout.activity_first_view_gone_first_line_single_item, + new Configuration() { + @Override + public void apply(FlexboxLayout flexboxLayout) { + flexboxLayout.setFlexDirection(FlexDirection.COLUMN); + } + }); + onView(withId(R.id.text2)).check(isTopAlignedWith(withId(R.id.flexbox_layout))); + onView(withId(R.id.text2)).check(isLeftAlignedWith(withId(R.id.flexbox_layout))); + onView(withId(R.id.text3)).check(isTopAlignedWith(withId(R.id.flexbox_layout))); + } + private FlexboxLayout createFlexboxLayout(@LayoutRes final int activityLayoutResId) throws Throwable { return createFlexboxLayout(activityLayoutResId, Configuration.EMPTY); diff --git a/flexbox/src/androidTest/res/layout/activity_first_view_gone_first_line_single_item.xml b/flexbox/src/androidTest/res/layout/activity_first_view_gone_first_line_single_item.xml new file mode 100644 index 00000000..6de3ed9f --- /dev/null +++ b/flexbox/src/androidTest/res/layout/activity_first_view_gone_first_line_single_item.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + diff --git a/flexbox/src/main/java/com/google/android/flexbox/FlexboxLayout.java b/flexbox/src/main/java/com/google/android/flexbox/FlexboxLayout.java index 929d5e77..923240df 100644 --- a/flexbox/src/main/java/com/google/android/flexbox/FlexboxLayout.java +++ b/flexbox/src/main/java/com/google/android/flexbox/FlexboxLayout.java @@ -600,7 +600,6 @@ private void layoutHorizontal(boolean isRtl, int left, int top, int right, int b // Use float to reduce the round error that may happen in when justifyContent == // SPACE_BETWEEN or SPACE_AROUND float childLeft; - int currentViewIndex = 0; int height = bottom - top; int width = right - left; @@ -656,11 +655,9 @@ private void layoutHorizontal(boolean isRtl, int left, int top, int right, int b spaceBetweenItem = Math.max(spaceBetweenItem, 0); for (int j = 0; j < flexLine.mItemCount; j++) { - View child = getReorderedChildAt(currentViewIndex); - if (child == null) { - continue; - } else if (child.getVisibility() == View.GONE) { - currentViewIndex++; + int index = flexLine.mFirstIndex + j; + View child = getReorderedChildAt(index); + if (child == null || child.getVisibility() == View.GONE) { continue; } LayoutParams lp = ((LayoutParams) child.getLayoutParams()); @@ -668,7 +665,7 @@ private void layoutHorizontal(boolean isRtl, int left, int top, int right, int b childRight -= lp.rightMargin; int beforeDividerLength = 0; int endDividerLength = 0; - if (hasDividerBeforeChildAtAlongMainAxis(currentViewIndex, j)) { + if (hasDividerBeforeChildAtAlongMainAxis(index, j)) { beforeDividerLength = mDividerVerticalWidth; childLeft += beforeDividerLength; childRight -= beforeDividerLength; @@ -703,7 +700,6 @@ private void layoutHorizontal(boolean isRtl, int left, int top, int right, int b } childLeft += child.getMeasuredWidth() + spaceBetweenItem + lp.rightMargin; childRight -= child.getMeasuredWidth() + spaceBetweenItem + lp.leftMargin; - currentViewIndex++; if (isRtl) { flexLine.updatePositionFromView(child, /*leftDecoration*/endDividerLength, 0, @@ -747,7 +743,6 @@ private void layoutVertical(boolean isRtl, boolean fromBottomToTop, int left, in int paddingRight = getPaddingRight(); int childLeft = getPaddingLeft(); - int currentViewIndex = 0; int width = right - left; int height = bottom - top; @@ -805,11 +800,9 @@ private void layoutVertical(boolean isRtl, boolean fromBottomToTop, int left, in spaceBetweenItem = Math.max(spaceBetweenItem, 0); for (int j = 0; j < flexLine.mItemCount; j++) { - View child = getReorderedChildAt(currentViewIndex); - if (child == null) { - continue; - } else if (child.getVisibility() == View.GONE) { - currentViewIndex++; + int index = flexLine.mFirstIndex + j; + View child = getReorderedChildAt(index); + if (child == null || child.getVisibility() == View.GONE) { continue; } LayoutParams lp = ((LayoutParams) child.getLayoutParams()); @@ -817,7 +810,7 @@ private void layoutVertical(boolean isRtl, boolean fromBottomToTop, int left, in childBottom -= lp.bottomMargin; int beforeDividerLength = 0; int endDividerLength = 0; - if (hasDividerBeforeChildAtAlongMainAxis(currentViewIndex, j)) { + if (hasDividerBeforeChildAtAlongMainAxis(index, j)) { beforeDividerLength = mDividerHorizontalHeight; childTop += beforeDividerLength; childBottom -= beforeDividerLength; @@ -851,7 +844,6 @@ private void layoutVertical(boolean isRtl, boolean fromBottomToTop, int left, in } childTop += child.getMeasuredHeight() + spaceBetweenItem + lp.bottomMargin; childBottom -= child.getMeasuredHeight() + spaceBetweenItem + lp.topMargin; - currentViewIndex++; if (fromBottomToTop) { flexLine.updatePositionFromView(child, 0, /*topDecoration*/endDividerLength, 0,