Skip to content

Commit

Permalink
Fixes the wrong positioning (google#470)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
thagikura authored Nov 16, 2018
1 parent f5c49eb commit 27bacef
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3409,6 +3409,68 @@ class FlexboxLayoutManagerTest {
assertThat(layoutManager.flexLines.size, `is`(3))
}

@Test
@FlakyTest
@Throws(Throwable::class)
fun testNowrap_justifyContentCenter_directionRow() {
// This is to fix https://github.com/google/flexbox-layout/issues/469
val activity = activityRule.activity
val layoutManager = FlexboxLayoutManager(activity)
val adapter = TestAdapter()
val height = 70
activityRule.runOnUiThread {
activity.setContentView(R.layout.recyclerview)
val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
layoutManager.flexDirection = FlexDirection.ROW
layoutManager.flexWrap = FlexWrap.NOWRAP
layoutManager.justifyContent = JustifyContent.CENTER
recyclerView.layoutManager = layoutManager
recyclerView.adapter = adapter
for (i in 1..3) {
val lp = createLayoutParams(activity, 100, height)
adapter.addItem(lp)
}
}
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
val view1Bottom= layoutManager.getChildAt(0)!!.bottom
val view2Bottom = layoutManager.getChildAt(1)!!.bottom
val view3Bottom = layoutManager.getChildAt(2)!!.bottom
assertThat(view1Bottom, `is`(activity.dpToPixel(height)))
assertThat(view2Bottom, `is`(activity.dpToPixel(height)))
assertThat(view3Bottom, `is`(activity.dpToPixel(height)))
}

@Test
@FlakyTest
@Throws(Throwable::class)
fun testNowrap_justifyContentCenter_directionColumn() {
// This is to fix https://github.com/google/flexbox-layout/issues/469
val activity = activityRule.activity
val layoutManager = FlexboxLayoutManager(activity)
val adapter = TestAdapter()
val width = 100
activityRule.runOnUiThread {
activity.setContentView(R.layout.recyclerview)
val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
layoutManager.flexDirection = FlexDirection.COLUMN
layoutManager.flexWrap = FlexWrap.NOWRAP
layoutManager.justifyContent = JustifyContent.CENTER
recyclerView.layoutManager = layoutManager
recyclerView.adapter = adapter
for (i in 1..3) {
val lp = createLayoutParams(activity, width, 70)
adapter.addItem(lp)
}
}
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
val view1Right= layoutManager.getChildAt(0)!!.right
val view2Right = layoutManager.getChildAt(1)!!.right
val view3Right = layoutManager.getChildAt(2)!!.right
assertThat(view1Right, `is`(activity.dpToPixel(width)))
assertThat(view2Right, `is`(activity.dpToPixel(width)))
assertThat(view3Right, `is`(activity.dpToPixel(width)))
}

/**
* Creates a new flex item.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -789,15 +789,15 @@ private int fixLayoutStartGap(int startOffset, RecyclerView.Recycler recycler,
gap = mOrientationHelper.getEndAfterPadding() - startOffset;
if (gap > 0) {
// check if we should fix this gap.
fixOffset = handleScrollingCrossAxis(-gap, recycler, state);
fixOffset = handleScrollingMainOrientation(-gap, recycler, state);
} else {
return 0; // nothing to fix
}
} else {
gap = startOffset - mOrientationHelper.getStartAfterPadding();
if (gap > 0) {
// check if we should fix this gap.
fixOffset = -handleScrollingCrossAxis(gap, recycler, state);
fixOffset = -handleScrollingMainOrientation(gap, recycler, state);
} else {
return 0; // nothing to fix
}
Expand Down Expand Up @@ -828,14 +828,14 @@ private int fixLayoutEndGap(int endOffset, RecyclerView.Recycler recycler,
if (columnAndRtl) {
gap = endOffset - mOrientationHelper.getStartAfterPadding();
if (gap > 0) {
fixOffset = handleScrollingCrossAxis(gap, recycler, state);
fixOffset = handleScrollingMainOrientation(gap, recycler, state);
} else {
return 0; // nothing to fix
}
} else {
gap = mOrientationHelper.getEndAfterPadding() - endOffset;
if (gap > 0) {
fixOffset = -handleScrollingCrossAxis(-gap, recycler, state);
fixOffset = -handleScrollingMainOrientation(-gap, recycler, state);
} else {
return 0; // nothing to fix
}
Expand Down Expand Up @@ -1895,23 +1895,32 @@ public void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycl

@Override
public boolean canScrollHorizontally() {
return !isMainAxisDirectionHorizontal() || getWidth() > mParent.getWidth();
if (mFlexWrap == FlexWrap.NOWRAP) {
return isMainAxisDirectionHorizontal();
} else {
return !isMainAxisDirectionHorizontal() || getWidth() > mParent.getWidth();
}
}

@Override
public boolean canScrollVertically() {
return isMainAxisDirectionHorizontal() || getHeight() > mParent.getHeight();
if (mFlexWrap == FlexWrap.NOWRAP) {
return !isMainAxisDirectionHorizontal();
} else {
return isMainAxisDirectionHorizontal() || getHeight() > mParent.getHeight();
}
}

@Override
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
RecyclerView.State state) {
if (!isMainAxisDirectionHorizontal()) {
int scrolled = handleScrollingCrossAxis(dx, recycler, state);
if (!isMainAxisDirectionHorizontal() ||
(mFlexWrap == FlexWrap.NOWRAP && isMainAxisDirectionHorizontal())) {
int scrolled = handleScrollingMainOrientation(dx, recycler, state);
mViewCache.clear();
return scrolled;
} else {
int scrolled = handleScrollingMainAxis(dx);
int scrolled = handleScrollingSubOrientation(dx);
mAnchorInfo.mPerpendicularCoordinate += scrolled;
mSubOrientationHelper.offsetChildren(-scrolled);
return scrolled;
Expand All @@ -1921,26 +1930,29 @@ public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
@Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
RecyclerView.State state) {
if (isMainAxisDirectionHorizontal()) {
int scrolled = handleScrollingCrossAxis(dy, recycler, state);
if (isMainAxisDirectionHorizontal() ||
(mFlexWrap == FlexWrap.NOWRAP && !isMainAxisDirectionHorizontal())) {
int scrolled = handleScrollingMainOrientation(dy, recycler, state);
mViewCache.clear();
return scrolled;
} else {
int scrolled = handleScrollingMainAxis(dy);
int scrolled = handleScrollingSubOrientation(dy);
mAnchorInfo.mPerpendicularCoordinate += scrolled;
mSubOrientationHelper.offsetChildren(-scrolled);
return scrolled;
}
}

/**
* Handle the scrolling along the direction of {@link #mOrientationHelper}.
*
* @param delta the delta for the amount that is being scrolled
* (either horizontally or vertically)
* @param recycler the Recycler instance
* @param state the Recycler.State instance
* @return the amount actually scrolled
*/
private int handleScrollingCrossAxis(int delta, RecyclerView.Recycler recycler,
private int handleScrollingMainOrientation(int delta, RecyclerView.Recycler recycler,
RecyclerView.State state) {
if (getChildCount() == 0 || delta == 0) {
return 0;
Expand Down Expand Up @@ -1974,7 +1986,14 @@ private int handleScrollingCrossAxis(int delta, RecyclerView.Recycler recycler,
return scrolled;
}

private int handleScrollingMainAxis(int delta) {
/**
* Handle the scrolling along the direction of {@link #mSubOrientationHelper}.
*
* @param delta the delta for the amount that is being scrolled
* (either horizontally or vertically)
* @return the amount actually scrolled
*/
private int handleScrollingSubOrientation(int delta) {
if (getChildCount() == 0 || delta == 0) {
return 0;
}
Expand Down Expand Up @@ -2869,21 +2888,30 @@ private void assignCoordinateFromPadding() {
}

private void assignFromView(View anchor) {
OrientationHelper orientationHelper;
// When the flex wrap is nowrap, the orientation helper is changed to
// perpendicular. Need to use the mSubOrientationHelper to be consistent with
// when flex wrap is not nowrap.
if (mFlexWrap == FlexWrap.NOWRAP) {
orientationHelper = mSubOrientationHelper;
} else {
orientationHelper = mOrientationHelper;
}
if (!isMainAxisDirectionHorizontal() && mIsRtl) {
// We need to use the anchor view as starting from right if the flex direction is
// (column or column_reverse) and layout direction is RTL.
if (mLayoutFromEnd) {
mCoordinate = mOrientationHelper.getDecoratedStart(anchor) +
mOrientationHelper.getTotalSpaceChange();
mCoordinate = orientationHelper.getDecoratedStart(anchor) +
orientationHelper.getTotalSpaceChange();
} else {
mCoordinate = mOrientationHelper.getDecoratedEnd(anchor);
mCoordinate = orientationHelper.getDecoratedEnd(anchor);
}
} else {
if (mLayoutFromEnd) {
mCoordinate = mOrientationHelper.getDecoratedEnd(anchor) +
mOrientationHelper.getTotalSpaceChange();
mCoordinate = orientationHelper.getDecoratedEnd(anchor) +
orientationHelper.getTotalSpaceChange();
} else {
mCoordinate = mOrientationHelper.getDecoratedStart(anchor);
mCoordinate = orientationHelper.getDecoratedStart(anchor);
}
}
mPosition = getPosition(anchor);
Expand Down

0 comments on commit 27bacef

Please sign in to comment.