diff --git a/flexbox/src/androidTest/java/com/google/android/flexbox/test/FlexboxLayoutManagerConfigChangeTest.kt b/flexbox/src/androidTest/java/com/google/android/flexbox/test/FlexboxLayoutManagerConfigChangeTest.kt index e21a4582..ec2ac33a 100644 --- a/flexbox/src/androidTest/java/com/google/android/flexbox/test/FlexboxLayoutManagerConfigChangeTest.kt +++ b/flexbox/src/androidTest/java/com/google/android/flexbox/test/FlexboxLayoutManagerConfigChangeTest.kt @@ -31,6 +31,7 @@ import androidx.test.filters.MediumTest import androidx.test.rule.ActivityTestRule import androidx.test.runner.AndroidJUnit4 import com.google.android.flexbox.FlexDirection +import com.google.android.flexbox.FlexWrap import com.google.android.flexbox.FlexboxLayoutManager import org.hamcrest.Matchers.`is` import org.hamcrest.core.IsNot.not @@ -100,6 +101,181 @@ class FlexboxLayoutManagerConfigChangeTest { assertThat(firstLine.mainSize, `is`(not(firstLineAfterRotation.mainSize))) } + + @Test + @FlakyTest + @Throws(Throwable::class) + fun testPaddingTop_row_nowrap_topless() { + val activity = activityRule.activity + val layoutManager = FlexboxLayoutManager(activity) + layoutManager.flexWrap = FlexWrap.NOWRAP + layoutManager.flexDirection = FlexDirection.ROW + val adapter = TestAdapter() + val topPadding = 0 + val leftPadding = 20 + activityRule.runOnUiThread{ + activity.setContentView(R.layout.recyclerview) + val recyclerView = activity.findViewById(R.id.recyclerview) + recyclerView.setPadding(leftPadding, topPadding, 0,0) + recyclerView.layoutManager = layoutManager + recyclerView.adapter = adapter + for (i in 0..20) { + var lp = createLayoutParams(activity, 80, 50) + adapter.addItem(lp) + } + } + InstrumentationRegistry.getInstrumentation().waitForIdleSync() + + val firstChild = layoutManager.getChildAt(0)!! + val lastChild = layoutManager.getChildAt(layoutManager.childCount - 1)!! + assertThat(firstChild.top, IsEqualAllowingError.isEqualAllowingError(topPadding)) + assertThat(firstChild.left, IsEqualAllowingError.isEqualAllowingError(leftPadding)) + assertThat(lastChild.top, IsEqualAllowingError.isEqualAllowingError(topPadding)) + + activityRule.runOnUiThread { + val orientation = activity.resources.configuration.orientation + if (orientation == Configuration.ORIENTATION_PORTRAIT) { + activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE + } else { + activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + } + } + InstrumentationRegistry.getInstrumentation().waitForIdleSync() + + val firstChildAfterRotate = layoutManager.getChildAt(0)!! + val lastChildAfterRotate = layoutManager.getChildAt(layoutManager.childCount - 1)!! + assertThat(firstChildAfterRotate.top, IsEqualAllowingError.isEqualAllowingError(topPadding)) + assertThat(firstChildAfterRotate.left, IsEqualAllowingError.isEqualAllowingError(leftPadding)) + assertThat(lastChildAfterRotate.top, IsEqualAllowingError.isEqualAllowingError(topPadding)) + + activityRule.runOnUiThread { + val orientation = activity.resources.configuration.orientation + if (orientation == Configuration.ORIENTATION_PORTRAIT) { + activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE + } else { + activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + } + } + InstrumentationRegistry.getInstrumentation().waitForIdleSync() + + } + + @Test + @FlakyTest + @Throws(Throwable::class) + fun testPaddingTop_row_nowrap_leftless() { + val activity = activityRule.activity + val layoutManager = FlexboxLayoutManager(activity) + layoutManager.flexWrap = FlexWrap.NOWRAP + layoutManager.flexDirection = FlexDirection.ROW + val adapter = TestAdapter() + val topPadding = 40 + val leftPadding = 20 + activityRule.runOnUiThread{ + activity.setContentView(R.layout.recyclerview) + val recyclerView = activity.findViewById(R.id.recyclerview) + recyclerView.setPadding(leftPadding, topPadding, 0,0) + recyclerView.layoutManager = layoutManager + recyclerView.adapter = adapter + for (i in 0..20) { + var lp = createLayoutParams(activity, 80, 50) + adapter.addItem(lp) + } + } + InstrumentationRegistry.getInstrumentation().waitForIdleSync() + + val firstChild = layoutManager.getChildAt(0)!! + val lastChild = layoutManager.getChildAt(layoutManager.childCount - 1)!! + assertThat(firstChild.top, IsEqualAllowingError.isEqualAllowingError(topPadding)) + assertThat(firstChild.left, IsEqualAllowingError.isEqualAllowingError(leftPadding)) + assertThat(lastChild.top, IsEqualAllowingError.isEqualAllowingError(topPadding)) + + activityRule.runOnUiThread { + val orientation = activity.resources.configuration.orientation + if (orientation == Configuration.ORIENTATION_PORTRAIT) { + activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE + } else { + activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + } + } + InstrumentationRegistry.getInstrumentation().waitForIdleSync() + + val firstChildAfterRotate = layoutManager.getChildAt(0)!! + val lastChildAfterRotate = layoutManager.getChildAt(layoutManager.childCount - 1)!! + assertThat(firstChildAfterRotate.top, IsEqualAllowingError.isEqualAllowingError(topPadding)) + assertThat(firstChildAfterRotate.left, IsEqualAllowingError.isEqualAllowingError(leftPadding)) + assertThat(lastChildAfterRotate.top, IsEqualAllowingError.isEqualAllowingError(topPadding)) + + activityRule.runOnUiThread { + val orientation = activity.resources.configuration.orientation + if (orientation == Configuration.ORIENTATION_PORTRAIT) { + activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE + } else { + activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + } + } + InstrumentationRegistry.getInstrumentation().waitForIdleSync() + + } + + @Test + @FlakyTest + @Throws(Throwable::class) + fun testPaddingTop_column_nowrap_topless() { + val activity = activityRule.activity + val layoutManager = FlexboxLayoutManager(activity) + layoutManager.flexWrap = FlexWrap.NOWRAP + layoutManager.flexDirection = FlexDirection.COLUMN + val adapter = TestAdapter() + val topPadding = 0 + val leftPadding = 20 + activityRule.runOnUiThread{ + activity.setContentView(R.layout.recyclerview) + val recyclerView = activity.findViewById(R.id.recyclerview) + recyclerView.setPadding(leftPadding, topPadding, 0,0) + recyclerView.layoutManager = layoutManager + recyclerView.adapter = adapter + for (i in 0..20) { + var lp = createLayoutParams(activity, 80, 50) + adapter.addItem(lp) + } + } + InstrumentationRegistry.getInstrumentation().waitForIdleSync() + + val firstChild = layoutManager.getChildAt(0)!! + val lastChild = layoutManager.getChildAt(layoutManager.childCount - 1)!! + assertThat(firstChild.top, IsEqualAllowingError.isEqualAllowingError(topPadding)) + assertThat(firstChild.left, IsEqualAllowingError.isEqualAllowingError(leftPadding)) + assertThat(lastChild.left, IsEqualAllowingError.isEqualAllowingError(leftPadding)) + + activityRule.runOnUiThread { + val orientation = activity.resources.configuration.orientation + if (orientation == Configuration.ORIENTATION_PORTRAIT) { + activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE + } else { + activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + } + } + InstrumentationRegistry.getInstrumentation().waitForIdleSync() + + val firstChildAfterRotate = layoutManager.getChildAt(0)!! + val lastChildAfterRotate = layoutManager.getChildAt(layoutManager.childCount - 1)!! + assertThat(firstChildAfterRotate.top, IsEqualAllowingError.isEqualAllowingError(topPadding)) + assertThat(firstChildAfterRotate.left, IsEqualAllowingError.isEqualAllowingError(leftPadding)) + assertThat(lastChildAfterRotate.left, IsEqualAllowingError.isEqualAllowingError(leftPadding)) + + activityRule.runOnUiThread { + val orientation = activity.resources.configuration.orientation + if (orientation == Configuration.ORIENTATION_PORTRAIT) { + activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE + } else { + activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + } + } + InstrumentationRegistry.getInstrumentation().waitForIdleSync() + + } + @Test @FlakyTest @Throws(Throwable::class) diff --git a/flexbox/src/main/java/com/google/android/flexbox/FlexboxLayoutManager.java b/flexbox/src/main/java/com/google/android/flexbox/FlexboxLayoutManager.java index 35bef60b..6103b97a 100644 --- a/flexbox/src/main/java/com/google/android/flexbox/FlexboxLayoutManager.java +++ b/flexbox/src/main/java/com/google/android/flexbox/FlexboxLayoutManager.java @@ -1076,7 +1076,10 @@ private boolean updateAnchorFromPendingState(RecyclerView.State state, AnchorInf anchorInfo.mPosition = mPendingScrollPosition; anchorInfo.mFlexLinePosition = mFlexboxHelper.mIndexToFlexLine[anchorInfo.mPosition]; if (mPendingSavedState != null && mPendingSavedState.hasValidAnchor(state.getItemCount())) { - anchorInfo.mCoordinate = mOrientationHelper.getStartAfterPadding() + + OrientationHelper tempOrientationHelper = mFlexWrap == FlexWrap.NOWRAP? + mSubOrientationHelper + : mOrientationHelper; + anchorInfo.mCoordinate = tempOrientationHelper.getStartAfterPadding() + savedState.mAnchorOffset; anchorInfo.mAssignedFromSavedState = true; anchorInfo.mFlexLinePosition = NO_POSITION; @@ -1121,11 +1124,14 @@ private boolean updateAnchorFromPendingState(RecyclerView.State state, AnchorInf } // TODO: Support reverse layout when flex wrap == FlexWrap.WRAP_REVERSE + OrientationHelper tempOrientationHelper = mFlexWrap == FlexWrap.NOWRAP + ? mSubOrientationHelper + : mOrientationHelper; if (!isMainAxisDirectionHorizontal() && mIsRtl) { anchorInfo.mCoordinate = mPendingScrollPositionOffset - - mOrientationHelper.getEndPadding(); + - tempOrientationHelper.getEndPadding(); } else { - anchorInfo.mCoordinate = mOrientationHelper.getStartAfterPadding() + anchorInfo.mCoordinate = tempOrientationHelper.getStartAfterPadding() + mPendingScrollPositionOffset; } return true; @@ -1710,11 +1716,14 @@ private void updateLayoutStateToFillEnd(AnchorInfo anchorInfo, boolean fromNextL } else { mLayoutState.mInfinite = false; } + OrientationHelper orientationHelper = mFlexWrap == FlexWrap.NOWRAP + ? mSubOrientationHelper + : mOrientationHelper; if (!isMainAxisDirectionHorizontal() && mIsRtl) { mLayoutState.mAvailable = anchorInfo.mCoordinate - getPaddingRight(); } else { - mLayoutState.mAvailable = - mOrientationHelper.getEndAfterPadding() - anchorInfo.mCoordinate; + mLayoutState.mAvailable = orientationHelper.getEndAfterPadding() + - anchorInfo.mCoordinate; } mLayoutState.mPosition = anchorInfo.mPosition; mLayoutState.mItemDirection = LayoutState.ITEM_DIRECTION_TAIL; @@ -1752,11 +1761,14 @@ private void updateLayoutStateToFillStart(AnchorInfo anchorInfo, boolean fromPre } else { mLayoutState.mInfinite = false; } + OrientationHelper orientationHelper = mFlexWrap == FlexWrap.NOWRAP + ? mSubOrientationHelper + : mOrientationHelper; if (!isMainAxisDirectionHorizontal() && mIsRtl) { mLayoutState.mAvailable = mParent.getWidth() - anchorInfo.mCoordinate - - mOrientationHelper.getStartAfterPadding(); + - orientationHelper.getStartAfterPadding(); } else { - mLayoutState.mAvailable = anchorInfo.mCoordinate - mOrientationHelper + mLayoutState.mAvailable = anchorInfo.mCoordinate - orientationHelper .getStartAfterPadding(); } mLayoutState.mPosition = anchorInfo.mPosition; @@ -2878,12 +2890,15 @@ private void reset() { } private void assignCoordinateFromPadding() { + OrientationHelper tempOrientationHelper = mFlexWrap == FlexWrap.NOWRAP + ? mSubOrientationHelper + : mOrientationHelper; if (!isMainAxisDirectionHorizontal() && mIsRtl) { - mCoordinate = mLayoutFromEnd ? mOrientationHelper.getEndAfterPadding() - : getWidth() - mOrientationHelper.getStartAfterPadding(); + mCoordinate = mLayoutFromEnd ? tempOrientationHelper.getEndAfterPadding() + : getWidth() - tempOrientationHelper.getStartAfterPadding(); } else { - mCoordinate = mLayoutFromEnd ? mOrientationHelper.getEndAfterPadding() - : mOrientationHelper.getStartAfterPadding(); + mCoordinate = mLayoutFromEnd ? tempOrientationHelper.getEndAfterPadding() + : tempOrientationHelper.getStartAfterPadding(); } }