Skip to content

Commit 27bacef

Browse files
authored
Fixes the wrong positioning (google#470)
Fixes the wrong positioning On the condition flexWrap = No wrap and justifyContent = center. This happened because when flexWrap = no wrap, the anchor position retrieved from the existing view was wrong. Because the OrientationHelper is changed to perpendicularly when flexWrap is nowrap.
1 parent f5c49eb commit 27bacef

File tree

2 files changed

+110
-20
lines changed

2 files changed

+110
-20
lines changed

flexbox/src/androidTest/java/com/google/android/flexbox/test/FlexboxLayoutManagerTest.kt

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3409,6 +3409,68 @@ class FlexboxLayoutManagerTest {
34093409
assertThat(layoutManager.flexLines.size, `is`(3))
34103410
}
34113411

3412+
@Test
3413+
@FlakyTest
3414+
@Throws(Throwable::class)
3415+
fun testNowrap_justifyContentCenter_directionRow() {
3416+
// This is to fix https://github.com/google/flexbox-layout/issues/469
3417+
val activity = activityRule.activity
3418+
val layoutManager = FlexboxLayoutManager(activity)
3419+
val adapter = TestAdapter()
3420+
val height = 70
3421+
activityRule.runOnUiThread {
3422+
activity.setContentView(R.layout.recyclerview)
3423+
val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
3424+
layoutManager.flexDirection = FlexDirection.ROW
3425+
layoutManager.flexWrap = FlexWrap.NOWRAP
3426+
layoutManager.justifyContent = JustifyContent.CENTER
3427+
recyclerView.layoutManager = layoutManager
3428+
recyclerView.adapter = adapter
3429+
for (i in 1..3) {
3430+
val lp = createLayoutParams(activity, 100, height)
3431+
adapter.addItem(lp)
3432+
}
3433+
}
3434+
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
3435+
val view1Bottom= layoutManager.getChildAt(0)!!.bottom
3436+
val view2Bottom = layoutManager.getChildAt(1)!!.bottom
3437+
val view3Bottom = layoutManager.getChildAt(2)!!.bottom
3438+
assertThat(view1Bottom, `is`(activity.dpToPixel(height)))
3439+
assertThat(view2Bottom, `is`(activity.dpToPixel(height)))
3440+
assertThat(view3Bottom, `is`(activity.dpToPixel(height)))
3441+
}
3442+
3443+
@Test
3444+
@FlakyTest
3445+
@Throws(Throwable::class)
3446+
fun testNowrap_justifyContentCenter_directionColumn() {
3447+
// This is to fix https://github.com/google/flexbox-layout/issues/469
3448+
val activity = activityRule.activity
3449+
val layoutManager = FlexboxLayoutManager(activity)
3450+
val adapter = TestAdapter()
3451+
val width = 100
3452+
activityRule.runOnUiThread {
3453+
activity.setContentView(R.layout.recyclerview)
3454+
val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
3455+
layoutManager.flexDirection = FlexDirection.COLUMN
3456+
layoutManager.flexWrap = FlexWrap.NOWRAP
3457+
layoutManager.justifyContent = JustifyContent.CENTER
3458+
recyclerView.layoutManager = layoutManager
3459+
recyclerView.adapter = adapter
3460+
for (i in 1..3) {
3461+
val lp = createLayoutParams(activity, width, 70)
3462+
adapter.addItem(lp)
3463+
}
3464+
}
3465+
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
3466+
val view1Right= layoutManager.getChildAt(0)!!.right
3467+
val view2Right = layoutManager.getChildAt(1)!!.right
3468+
val view3Right = layoutManager.getChildAt(2)!!.right
3469+
assertThat(view1Right, `is`(activity.dpToPixel(width)))
3470+
assertThat(view2Right, `is`(activity.dpToPixel(width)))
3471+
assertThat(view3Right, `is`(activity.dpToPixel(width)))
3472+
}
3473+
34123474
/**
34133475
* Creates a new flex item.
34143476
*

flexbox/src/main/java/com/google/android/flexbox/FlexboxLayoutManager.java

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -789,15 +789,15 @@ private int fixLayoutStartGap(int startOffset, RecyclerView.Recycler recycler,
789789
gap = mOrientationHelper.getEndAfterPadding() - startOffset;
790790
if (gap > 0) {
791791
// check if we should fix this gap.
792-
fixOffset = handleScrollingCrossAxis(-gap, recycler, state);
792+
fixOffset = handleScrollingMainOrientation(-gap, recycler, state);
793793
} else {
794794
return 0; // nothing to fix
795795
}
796796
} else {
797797
gap = startOffset - mOrientationHelper.getStartAfterPadding();
798798
if (gap > 0) {
799799
// check if we should fix this gap.
800-
fixOffset = -handleScrollingCrossAxis(gap, recycler, state);
800+
fixOffset = -handleScrollingMainOrientation(gap, recycler, state);
801801
} else {
802802
return 0; // nothing to fix
803803
}
@@ -828,14 +828,14 @@ private int fixLayoutEndGap(int endOffset, RecyclerView.Recycler recycler,
828828
if (columnAndRtl) {
829829
gap = endOffset - mOrientationHelper.getStartAfterPadding();
830830
if (gap > 0) {
831-
fixOffset = handleScrollingCrossAxis(gap, recycler, state);
831+
fixOffset = handleScrollingMainOrientation(gap, recycler, state);
832832
} else {
833833
return 0; // nothing to fix
834834
}
835835
} else {
836836
gap = mOrientationHelper.getEndAfterPadding() - endOffset;
837837
if (gap > 0) {
838-
fixOffset = -handleScrollingCrossAxis(-gap, recycler, state);
838+
fixOffset = -handleScrollingMainOrientation(-gap, recycler, state);
839839
} else {
840840
return 0; // nothing to fix
841841
}
@@ -1895,23 +1895,32 @@ public void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycl
18951895

18961896
@Override
18971897
public boolean canScrollHorizontally() {
1898-
return !isMainAxisDirectionHorizontal() || getWidth() > mParent.getWidth();
1898+
if (mFlexWrap == FlexWrap.NOWRAP) {
1899+
return isMainAxisDirectionHorizontal();
1900+
} else {
1901+
return !isMainAxisDirectionHorizontal() || getWidth() > mParent.getWidth();
1902+
}
18991903
}
19001904

19011905
@Override
19021906
public boolean canScrollVertically() {
1903-
return isMainAxisDirectionHorizontal() || getHeight() > mParent.getHeight();
1907+
if (mFlexWrap == FlexWrap.NOWRAP) {
1908+
return !isMainAxisDirectionHorizontal();
1909+
} else {
1910+
return isMainAxisDirectionHorizontal() || getHeight() > mParent.getHeight();
1911+
}
19041912
}
19051913

19061914
@Override
19071915
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
19081916
RecyclerView.State state) {
1909-
if (!isMainAxisDirectionHorizontal()) {
1910-
int scrolled = handleScrollingCrossAxis(dx, recycler, state);
1917+
if (!isMainAxisDirectionHorizontal() ||
1918+
(mFlexWrap == FlexWrap.NOWRAP && isMainAxisDirectionHorizontal())) {
1919+
int scrolled = handleScrollingMainOrientation(dx, recycler, state);
19111920
mViewCache.clear();
19121921
return scrolled;
19131922
} else {
1914-
int scrolled = handleScrollingMainAxis(dx);
1923+
int scrolled = handleScrollingSubOrientation(dx);
19151924
mAnchorInfo.mPerpendicularCoordinate += scrolled;
19161925
mSubOrientationHelper.offsetChildren(-scrolled);
19171926
return scrolled;
@@ -1921,26 +1930,29 @@ public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
19211930
@Override
19221931
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
19231932
RecyclerView.State state) {
1924-
if (isMainAxisDirectionHorizontal()) {
1925-
int scrolled = handleScrollingCrossAxis(dy, recycler, state);
1933+
if (isMainAxisDirectionHorizontal() ||
1934+
(mFlexWrap == FlexWrap.NOWRAP && !isMainAxisDirectionHorizontal())) {
1935+
int scrolled = handleScrollingMainOrientation(dy, recycler, state);
19261936
mViewCache.clear();
19271937
return scrolled;
19281938
} else {
1929-
int scrolled = handleScrollingMainAxis(dy);
1939+
int scrolled = handleScrollingSubOrientation(dy);
19301940
mAnchorInfo.mPerpendicularCoordinate += scrolled;
19311941
mSubOrientationHelper.offsetChildren(-scrolled);
19321942
return scrolled;
19331943
}
19341944
}
19351945

19361946
/**
1947+
* Handle the scrolling along the direction of {@link #mOrientationHelper}.
1948+
*
19371949
* @param delta the delta for the amount that is being scrolled
19381950
* (either horizontally or vertically)
19391951
* @param recycler the Recycler instance
19401952
* @param state the Recycler.State instance
19411953
* @return the amount actually scrolled
19421954
*/
1943-
private int handleScrollingCrossAxis(int delta, RecyclerView.Recycler recycler,
1955+
private int handleScrollingMainOrientation(int delta, RecyclerView.Recycler recycler,
19441956
RecyclerView.State state) {
19451957
if (getChildCount() == 0 || delta == 0) {
19461958
return 0;
@@ -1974,7 +1986,14 @@ private int handleScrollingCrossAxis(int delta, RecyclerView.Recycler recycler,
19741986
return scrolled;
19751987
}
19761988

1977-
private int handleScrollingMainAxis(int delta) {
1989+
/**
1990+
* Handle the scrolling along the direction of {@link #mSubOrientationHelper}.
1991+
*
1992+
* @param delta the delta for the amount that is being scrolled
1993+
* (either horizontally or vertically)
1994+
* @return the amount actually scrolled
1995+
*/
1996+
private int handleScrollingSubOrientation(int delta) {
19781997
if (getChildCount() == 0 || delta == 0) {
19791998
return 0;
19801999
}
@@ -2869,21 +2888,30 @@ private void assignCoordinateFromPadding() {
28692888
}
28702889

28712890
private void assignFromView(View anchor) {
2891+
OrientationHelper orientationHelper;
2892+
// When the flex wrap is nowrap, the orientation helper is changed to
2893+
// perpendicular. Need to use the mSubOrientationHelper to be consistent with
2894+
// when flex wrap is not nowrap.
2895+
if (mFlexWrap == FlexWrap.NOWRAP) {
2896+
orientationHelper = mSubOrientationHelper;
2897+
} else {
2898+
orientationHelper = mOrientationHelper;
2899+
}
28722900
if (!isMainAxisDirectionHorizontal() && mIsRtl) {
28732901
// We need to use the anchor view as starting from right if the flex direction is
28742902
// (column or column_reverse) and layout direction is RTL.
28752903
if (mLayoutFromEnd) {
2876-
mCoordinate = mOrientationHelper.getDecoratedStart(anchor) +
2877-
mOrientationHelper.getTotalSpaceChange();
2904+
mCoordinate = orientationHelper.getDecoratedStart(anchor) +
2905+
orientationHelper.getTotalSpaceChange();
28782906
} else {
2879-
mCoordinate = mOrientationHelper.getDecoratedEnd(anchor);
2907+
mCoordinate = orientationHelper.getDecoratedEnd(anchor);
28802908
}
28812909
} else {
28822910
if (mLayoutFromEnd) {
2883-
mCoordinate = mOrientationHelper.getDecoratedEnd(anchor) +
2884-
mOrientationHelper.getTotalSpaceChange();
2911+
mCoordinate = orientationHelper.getDecoratedEnd(anchor) +
2912+
orientationHelper.getTotalSpaceChange();
28852913
} else {
2886-
mCoordinate = mOrientationHelper.getDecoratedStart(anchor);
2914+
mCoordinate = orientationHelper.getDecoratedStart(anchor);
28872915
}
28882916
}
28892917
mPosition = getPosition(anchor);

0 commit comments

Comments
 (0)