Merge "Update scroll up and down behavior" into rvc-qpr-dev
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiRecyclerViewTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiRecyclerViewTest.java
index e1ec9e9..ea4a8c3 100644
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiRecyclerViewTest.java
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/CarUiRecyclerViewTest.java
@@ -41,8 +41,10 @@
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.lessThan;
+import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -334,7 +336,14 @@
onView(withId(R.id.list)).check(matches(isDisplayed()));
CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
- FixedSizeTestAdapter adapter = new FixedSizeTestAdapter(50, carUiRecyclerView.getHeight());
+
+ // Can't use OrientationHelper here, because it returns 0 when calling getTotalSpace methods
+ // until LayoutManager's onLayoutComplete is called. In this case waiting until the first
+ // item of the list is displayed guarantees that OrientationHelper is initialized properly.
+ int totalSpace = carUiRecyclerView.getHeight()
+ - carUiRecyclerView.getPaddingTop()
+ - carUiRecyclerView.getPaddingBottom();
+ PerfectFitTestAdapter adapter = new PerfectFitTestAdapter(5, totalSpace);
mActivity.runOnUiThread(() -> carUiRecyclerView.setAdapter(adapter));
IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
@@ -343,6 +352,9 @@
LinearLayoutManager layoutManager =
(LinearLayoutManager) carUiRecyclerView.getLayoutManager();
+ OrientationHelper orientationHelper = OrientationHelper.createVerticalHelper(layoutManager);
+ assertEquals(totalSpace, orientationHelper.getTotalSpace());
+
// Move down one page so there will be sufficient pages for up and downs.
onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
@@ -513,46 +525,48 @@
});
IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+ onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
OrientationHelper orientationHelper =
OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
-
- int screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;
+ int screenHeight = orientationHelper.getTotalSpace();
// Scroll to a position where long item is partially visible.
// Scrolling from top, scrollToPosition() aligns the pos-1 item to bottom.
onView(withId(R.id.list)).perform(scrollToPosition(longItemPosition - 1));
// Scroll by half the height of the screen so the long item is partially visible.
mActivity.runOnUiThread(() -> carUiRecyclerView.scrollBy(0, screenHeight / 2));
-
- onView(withText(adapter.getItemText(longItemPosition))).check(matches(isDisplayed()));
+ // This is needed to make sure scroll is finished before looking for the long item.
+ onView(withText(adapter.getItemText(longItemPosition - 1))).check(matches(isDisplayed()));
// Verify long item is partially shown.
View longItem = getLongItem(carUiRecyclerView);
assertThat(
orientationHelper.getDecoratedStart(longItem),
- is(greaterThan(carUiRecyclerView.getTop())));
+ is(greaterThan(orientationHelper.getStartAfterPadding())));
onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
// Verify long item is snapped to top.
- assertThat(orientationHelper.getDecoratedStart(longItem), is(equalTo(0)));
+ assertThat(orientationHelper.getDecoratedStart(longItem),
+ is(equalTo(orientationHelper.getStartAfterPadding())));
assertThat(orientationHelper.getDecoratedEnd(longItem),
- is(greaterThan(carUiRecyclerView.getBottom())));
+ is(greaterThan(orientationHelper.getEndAfterPadding())));
// Set a limit to avoid test stuck in non-moving state.
- while (orientationHelper.getDecoratedEnd(longItem) > carUiRecyclerView.getBottom()) {
+ while (orientationHelper.getDecoratedEnd(longItem)
+ > orientationHelper.getEndAfterPadding()) {
onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
}
// Verify long item end is aligned to bottom.
assertThat(orientationHelper.getDecoratedEnd(longItem),
- is(equalTo(carUiRecyclerView.getHeight())));
+ is(equalTo(orientationHelper.getEndAfterPadding())));
onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
// Verify that the long item is no longer visible; Should be on the next child
assertThat(
orientationHelper.getDecoratedStart(longItem),
- is(lessThan(carUiRecyclerView.getTop())));
+ is(lessThan(orientationHelper.getStartAfterPadding())));
}
@Test
@@ -581,6 +595,7 @@
});
IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+ onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
OrientationHelper orientationHelper =
OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
@@ -595,9 +610,8 @@
View longItem = getLongItem(carUiRecyclerView);
// Making sure we've reached end of the recyclerview, after
// adding bottom padding
- assertThat(orientationHelper.getDecoratedEnd(longItem)
- + carUiRecyclerView.getPaddingBottom(),
- is(equalTo(carUiRecyclerView.getHeight())));
+ assertThat(orientationHelper.getDecoratedEnd(longItem),
+ is(equalTo(orientationHelper.getEndAfterPadding())));
}
@Test
@@ -621,6 +635,7 @@
});
IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+ onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
OrientationHelper orientationHelper =
OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
@@ -630,27 +645,25 @@
// Verify long item is off-screen.
View longItem = getLongItem(carUiRecyclerView);
+
assertThat(
orientationHelper.getDecoratedEnd(longItem),
- is(greaterThan(carUiRecyclerView.getTop())));
+ is(lessThanOrEqualTo(orientationHelper.getEndAfterPadding())));
- onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click());
-
- // Verify long item is snapped to bottom.
- assertThat(orientationHelper.getDecoratedEnd(longItem),
- is(equalTo(carUiRecyclerView.getHeight())));
- assertThat(orientationHelper.getDecoratedStart(longItem), is(lessThan(0)));
-
-
- int decoratedStart = orientationHelper.getDecoratedStart(longItem);
-
- while (decoratedStart < 0) {
+ if (orientationHelper.getStartAfterPadding() - orientationHelper.getDecoratedStart(longItem)
+ < orientationHelper.getTotalSpace()) {
onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click());
- decoratedStart = orientationHelper.getDecoratedStart(longItem);
- }
+ assertThat(orientationHelper.getDecoratedStart(longItem),
+ is(greaterThanOrEqualTo(orientationHelper.getStartAfterPadding())));
+ } else {
+ int topBeforeClick = orientationHelper.getDecoratedStart(longItem);
- // Verify long item top is aligned to top.
- assertThat(orientationHelper.getDecoratedStart(longItem), is(equalTo(0)));
+ onView(withId(R.id.car_ui_scrollbar_page_up)).perform(click());
+
+ // Verify we scrolled 1 screen
+ assertThat(orientationHelper.getStartAfterPadding() - topBeforeClick,
+ is(equalTo(orientationHelper.getTotalSpace())));
+ }
}
@Test
@@ -674,6 +687,7 @@
});
IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+ onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
OrientationHelper orientationHelper =
OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
@@ -691,20 +705,21 @@
View longItem = getLongItem(carUiRecyclerView);
assertThat(
orientationHelper.getDecoratedStart(longItem),
- is(greaterThan(carUiRecyclerView.getTop())));
+ is(greaterThan(orientationHelper.getStartAfterPadding())));
onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
// Verify long item is snapped to top.
- assertThat(orientationHelper.getDecoratedStart(longItem), is(equalTo(0)));
+ assertThat(orientationHelper.getDecoratedStart(longItem),
+ is(equalTo(orientationHelper.getStartAfterPadding())));
assertThat(orientationHelper.getDecoratedEnd(longItem),
- is(greaterThan(carUiRecyclerView.getBottom())));
+ is(greaterThan(orientationHelper.getEndAfterPadding())));
onView(withId(R.id.car_ui_scrollbar_page_down)).perform(click());
// Verify long item does not snap to bottom.
assertThat(orientationHelper.getDecoratedEnd(longItem),
- not(equalTo(carUiRecyclerView.getHeight())));
+ not(equalTo(orientationHelper.getEndAfterPadding())));
}
@Test
@@ -733,6 +748,7 @@
});
IdlingRegistry.getInstance().register(new ScrollIdlingResource(carUiRecyclerView));
+ onView(withText(adapter.getItemText(0))).check(matches(isDisplayed()));
OrientationHelper orientationHelper =
OrientationHelper.createVerticalHelper(carUiRecyclerView.getLayoutManager());
@@ -747,12 +763,10 @@
View longItem = getLongItem(carUiRecyclerView);
// Making sure we've reached end of the recyclerview, after
// adding bottom padding
- assertThat(orientationHelper.getDecoratedEnd(longItem)
- + carUiRecyclerView.getPaddingBottom(),
- is(equalTo(carUiRecyclerView.getHeight())));
+ assertThat(orientationHelper.getDecoratedEnd(longItem),
+ is(equalTo(orientationHelper.getEndAfterPadding())));
}
-
@Test
public void testPageDownMaintainsMinimumScrollThumbTrackHeight() {
mActivity.runOnUiThread(
@@ -915,10 +929,12 @@
* @return An item that is taller than the CarUiRecyclerView.
*/
private View getLongItem(CarUiRecyclerView recyclerView) {
- for (int i = 0; i < recyclerView.getChildCount(); i++) {
- View item = recyclerView.getChildAt(i);
+ OrientationHelper orientationHelper =
+ OrientationHelper.createVerticalHelper(recyclerView.getLayoutManager());
+ for (int i = 0; i < recyclerView.getLayoutManager().getChildCount(); i++) {
+ View item = recyclerView.getLayoutManager().getChildAt(i);
- if (item.getHeight() > recyclerView.getHeight()) {
+ if (item.getHeight() > orientationHelper.getTotalSpace()) {
return item;
}
}
@@ -999,16 +1015,29 @@
}
}
- private static class FixedSizeTestAdapter extends RecyclerView.Adapter<TestViewHolder> {
+ private static class PerfectFitTestAdapter extends RecyclerView.Adapter<TestViewHolder> {
- private static final int ITEMS_PER_PAGE = 5;
+ private static final int MIN_HEIGHT = 30;
private final List<String> mData;
private final int mItemHeight;
- FixedSizeTestAdapter(int itemCount, int recyclerViewHeight) {
- mData = new ArrayList<>(itemCount);
- mItemHeight = recyclerViewHeight / ITEMS_PER_PAGE;
+ private int getMinHeightPerItemToFitScreen(int screenHeight) {
+ // When the height is a prime number, there can only be 1 item per page
+ int minHeight = screenHeight;
+ for (int i = screenHeight; i >= 1; i--) {
+ if (screenHeight % i == 0 && screenHeight / i >= MIN_HEIGHT) {
+ minHeight = screenHeight / i;
+ break;
+ }
+ }
+ return minHeight;
+ }
+ PerfectFitTestAdapter(int numOfPages, int recyclerViewHeight) {
+ mItemHeight = getMinHeightPerItemToFitScreen(recyclerViewHeight);
+ int itemsPerPage = recyclerViewHeight / mItemHeight;
+ int itemCount = itemsPerPage * numOfPages;
+ mData = new ArrayList<>(itemCount);
for (int i = 0; i < itemCount; i++) {
mData.add(getItemText(i));
}
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/DefaultScrollBar.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/DefaultScrollBar.java
index d44274c..2bed61c 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/DefaultScrollBar.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/DefaultScrollBar.java
@@ -19,6 +19,7 @@
import android.content.res.Resources;
import android.os.Handler;
+import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
@@ -26,6 +27,7 @@
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.recyclerview.widget.OrientationHelper;
import androidx.recyclerview.widget.RecyclerView;
@@ -260,13 +262,93 @@
.start();
}
+ private boolean mIsAdapterChangeObserverRegistered = false;
+ @Nullable
+ private RecyclerView.Adapter mCurrentAdapter;
private final RecyclerView.OnScrollListener mRecyclerViewOnScrollListener =
new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
updatePaginationButtons();
+ cacheChildrenHeight(recyclerView.getLayoutManager());
+ if (mCurrentAdapter != recyclerView.getAdapter()) {
+ mIsAdapterChangeObserverRegistered = false;
+ if (mCurrentAdapter != null) {
+ mCurrentAdapter.unregisterAdapterDataObserver(mAdapterChangeObserver);
+ }
+ }
+ if (!mIsAdapterChangeObserverRegistered
+ && recyclerView.getAdapter() != null) {
+ mIsAdapterChangeObserverRegistered = true;
+ mCurrentAdapter = recyclerView.getAdapter();
+ mCurrentAdapter.registerAdapterDataObserver(mAdapterChangeObserver);
+ }
}
};
+ private final SparseArray<Integer> mChildHeightByAdapterPosition = new SparseArray();
+
+ private final RecyclerView.AdapterDataObserver mAdapterChangeObserver =
+ new RecyclerView.AdapterDataObserver() {
+ @Override
+ public void onChanged() {
+ clearCachedHeights();
+ }
+ @Override
+ public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
+ clearCachedHeights();
+ }
+ @Override
+ public void onItemRangeChanged(int positionStart, int itemCount) {
+ clearCachedHeights();
+ }
+ @Override
+ public void onItemRangeInserted(int positionStart, int itemCount) {
+ clearCachedHeights();
+ }
+ @Override
+ public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
+ clearCachedHeights();
+ }
+ @Override
+ public void onItemRangeRemoved(int positionStart, int itemCount) {
+ clearCachedHeights();
+ }
+ };
+
+ private void clearCachedHeights() {
+ mChildHeightByAdapterPosition.clear();
+ cacheChildrenHeight(mRecyclerView.getLayoutManager());
+ }
+
+ private void cacheChildrenHeight(RecyclerView.LayoutManager layoutManager) {
+ for (int i = 0; i < layoutManager.getChildCount(); i++) {
+ View child = layoutManager.getChildAt(i);
+ int childPosition = layoutManager.getPosition(child);
+ if (mChildHeightByAdapterPosition.indexOfKey(childPosition) < 0) {
+ mChildHeightByAdapterPosition.put(childPosition, child.getHeight());
+ }
+ }
+ }
+
+ private int estimateNextPositionScrollUp(int currentPos, int scrollDistance,
+ OrientationHelper orientationHelper) {
+ int nextPos = 0;
+ int distance = 0;
+ for (int i = currentPos - 1; i >= 0; i--) {
+ if (mChildHeightByAdapterPosition.indexOfKey(i) < 0) {
+ // Use the average height estimate when there is not enough data
+ nextPos = mSnapHelper.estimateNextPositionDiffForScrollDistance(orientationHelper,
+ -scrollDistance);
+ break;
+ }
+ if ((distance + mChildHeightByAdapterPosition.get(i)) > Math.abs(scrollDistance)) {
+ nextPos = i - currentPos + 1;
+ break;
+ }
+ distance += mChildHeightByAdapterPosition.get(i);
+ }
+ return nextPos;
+ }
private OrientationHelper getOrientationHelper(RecyclerView.LayoutManager layoutManager) {
if (mOrientationHelper == null || mOrientationHelper.getLayoutManager() != layoutManager) {
@@ -295,52 +377,38 @@
OrientationHelper orientationHelper = getOrientationHelper(layoutManager);
int screenSize = orientationHelper.getTotalSpace();
int scrollDistance = screenSize;
- boolean isPageUpOverLongItem;
- // The iteration order matters. In case where there are 2 items longer than screen size, we
- // want to focus on upcoming view.
- for (int i = 0; i < layoutManager.getChildCount(); i++) {
- /*
- * We treat child View longer than screen size differently:
- * 1) When it enters screen, next pageUp will align its bottom with parent bottom;
- * 2) When it leaves screen, next pageUp will align its top with parent top.
- */
- View child = layoutManager.getChildAt(i);
- if (child.getHeight() > screenSize) {
- if (orientationHelper.getDecoratedEnd(child) < screenSize) {
- // Child view bottom is entering screen. Align its bottom with parent bottom.
- scrollDistance = screenSize - orientationHelper.getDecoratedEnd(child);
- } else if (-screenSize < orientationHelper.getDecoratedStart(child)
- && orientationHelper.getDecoratedStart(child) < 0) {
- // Child view top is about to enter screen - its distance to parent top
- // is less than a full scroll. Align child top with parent top.
- scrollDistance = Math.abs(orientationHelper.getDecoratedStart(child));
- }
- // There can be two items that are longer than the screen. We stop at the first one.
- // This is affected by the iteration order.
- // Distance should always be positive. Negate its value to scroll up.
- mRecyclerView.smoothScrollBy(0, -scrollDistance);
- return;
- }
- }
-
- int nextPos = mSnapHelper.estimateNextPositionDiffForScrollDistance(orientationHelper,
- -scrollDistance);
- View currentPosView = getFirstFullyVisibleChild(orientationHelper);
+ View currentPosView = getFirstMostVisibleChild(orientationHelper);
int currentPos = currentPosView != null ? mRecyclerView.getLayoutManager().getPosition(
currentPosView) : 0;
- mRecyclerView.smoothScrollToPosition(Math.max(0, currentPos + nextPos));
+ int nextPos = estimateNextPositionScrollUp(currentPos,
+ scrollDistance - Math.max(0, orientationHelper.getStartAfterPadding()
+ - orientationHelper.getDecoratedStart(currentPosView)), orientationHelper);
+ if (nextPos == 0) {
+ // Distance should always be positive. Negate its value to scroll up.
+ mRecyclerView.smoothScrollBy(0, -scrollDistance);
+ } else {
+ mRecyclerView.smoothScrollToPosition(Math.max(0, currentPos + nextPos));
+ }
}
- private View getFirstFullyVisibleChild(OrientationHelper helper) {
- for (int i = 0; i < getRecyclerView().getChildCount(); i++) {
- View child = getRecyclerView().getChildAt(i);
- if (CarUiSnapHelper.getPercentageVisible(child, helper) == 1f) {
- return getRecyclerView().getChildAt(i);
+ private View getFirstMostVisibleChild(OrientationHelper helper) {
+ float mostVisiblePercent = 0;
+ View mostVisibleView = null;
+
+ for (int i = 0; i < getRecyclerView().getLayoutManager().getChildCount(); i++) {
+ View child = getRecyclerView().getLayoutManager().getChildAt(i);
+ float visiblePercentage = CarUiSnapHelper.getPercentageVisible(child, helper);
+ if (visiblePercentage == 1f) {
+ mostVisibleView = child;
+ break;
+ } else if (visiblePercentage > mostVisiblePercent) {
+ mostVisiblePercent = visiblePercentage;
+ mostVisibleView = child;
}
}
- return null;
+ return mostVisibleView;
}
/**
@@ -361,43 +429,46 @@
int screenSize = orientationHelper.getTotalSpace();
int scrollDistance = screenSize;
- // If the last item is partially visible, page down should bring it to the top.
- View lastChild = layoutManager.getChildAt(layoutManager.getChildCount() - 1);
- if (layoutManager.isViewPartiallyVisible(lastChild,
- /* completelyVisible= */ false, /* acceptEndPointInclusion= */ false)) {
- scrollDistance = orientationHelper.getDecoratedStart(lastChild)
- - orientationHelper.getStartAfterPadding();
- if (scrollDistance <= 0) {
- // - Scroll value is zero if the top of last item is aligned with top of the screen;
- // - Scroll value can be negative if the child is longer than the screen size and
- // the visible area of the screen does not show the start of the child.
- // Scroll to the next screen in both cases.
- scrollDistance = screenSize;
- }
+ View currentPosView = getFirstMostVisibleChild(orientationHelper);
+
+ // If current view is partially visible and bottom of the view is below visible area of
+ // the recyclerview either scroll down one page (screenSize) or enough to align the bottom
+ // of the view with the bottom of the recyclerview. Note that this will not cause a snap,
+ // because the current view is already snapped to the top or it wouldn't be the most
+ // visible view.
+ if (layoutManager.isViewPartiallyVisible(currentPosView,
+ /* completelyVisible= */ false, /* acceptEndPointInclusion= */ false)
+ && orientationHelper.getDecoratedEnd(currentPosView)
+ > orientationHelper.getEndAfterPadding()) {
+ scrollDistance = Math.min(screenSize,
+ orientationHelper.getDecoratedEnd(currentPosView)
+ - orientationHelper.getEndAfterPadding());
}
- // The iteration order matters. In case where there are 2 items longer than screen size, we
- // want to focus on upcoming view (the one at the bottom of screen).
+ // Iterate over the childview (bottom to top) and stop when we find the first
+ // view that we can snap to and the scroll size is less than max scroll size (screenSize)
for (int i = layoutManager.getChildCount() - 1; i >= 0; i--) {
- /* We treat child View longer than screen size differently:
- * 1) When it enters screen, next pageDown will align its top with parent top;
- * 2) When it leaves screen, next pageDown will align its bottom with parent bottom.
- */
View child = layoutManager.getChildAt(i);
- if (child.getHeight() > screenSize) {
- if (orientationHelper.getDecoratedStart(child)
- - orientationHelper.getStartAfterPadding() > 0) {
- // Child view top is entering screen. Align its top with parent top.
- scrollDistance = orientationHelper.getDecoratedStart(lastChild)
+
+ // Ignore the child if it's above the currentview, as scrolldown will only move down.
+ // Note that in case of gridview, child will not be the same as the currentview.
+ if (orientationHelper.getDecoratedStart(child)
+ <= orientationHelper.getDecoratedStart(currentPosView)) {
+ break;
+ }
+
+ // Ignore the child if the scroll distance is bigger than the max scroll size
+ if (orientationHelper.getDecoratedStart(child)
+ - orientationHelper.getStartAfterPadding() <= screenSize) {
+ // If the child is already fully visible we can scroll even further.
+ if (orientationHelper.getDecoratedEnd(child)
+ <= orientationHelper.getEndAfterPadding()) {
+ scrollDistance = orientationHelper.getDecoratedEnd(child)
- orientationHelper.getStartAfterPadding();
- } else if (screenSize < orientationHelper.getDecoratedEnd(child)
- && orientationHelper.getDecoratedEnd(child) < 2 * screenSize) {
- // Child view bottom is about to enter screen - its distance to parent bottom
- // is less than a full scroll. Align child bottom with parent bottom.
- scrollDistance = orientationHelper.getDecoratedEnd(child) - screenSize;
+ } else {
+ scrollDistance = orientationHelper.getDecoratedStart(child)
+ - orientationHelper.getStartAfterPadding();
}
- // There can be two items that are longer than the screen. We stop at the first one.
- // This is affected by the iteration order.
break;
}
}