diff --git a/lib/java/com/google/android/material/carousel/CarouselLayoutManager.java b/lib/java/com/google/android/material/carousel/CarouselLayoutManager.java index 6965ab43969..083f9f83dbf 100644 --- a/lib/java/com/google/android/material/carousel/CarouselLayoutManager.java +++ b/lib/java/com/google/android/material/carousel/CarouselLayoutManager.java @@ -419,10 +419,10 @@ private void logChildrenIfDebugging() { Log.d(TAG, "internal representation of views on the screen"); for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); - float centerX = getDecoratedCenterXWithMargins(child); + float center = getDecoratedCenterWithMargins(child); Log.d( TAG, - "item position " + getPosition(child) + ", center:" + centerX + ", child index:" + i); + "item position " + getPosition(child) + ", center:" + center + ", child index:" + i); } Log.d(TAG, "=============="); } @@ -560,22 +560,30 @@ private boolean isLocOffsetOutOfFillBoundsEnd(float locOffset, KeylineRange rang @Override public void getDecoratedBoundsWithMargins(@NonNull View view, @NonNull Rect outBounds) { super.getDecoratedBoundsWithMargins(view, outBounds); - float centerX = outBounds.centerX(); + float center = outBounds.centerY(); + if (isHorizontal()) { + center = outBounds.centerX(); + } float maskedSize = getMaskedItemSizeForLocOffset( - centerX, getSurroundingKeylineRange(currentKeylineState.getKeylines(), centerX, true)); - float delta = (outBounds.width() - maskedSize) / 2F; + center, getSurroundingKeylineRange(currentKeylineState.getKeylines(), center, true)); + float deltaX = isHorizontal() ? (outBounds.width() - maskedSize) / 2F : 0; + float deltaY = isHorizontal() ? 0 : (outBounds.height() - maskedSize) / 2F; + outBounds.set( - (int) (outBounds.left + delta), - outBounds.top, - (int) (outBounds.right - delta), - outBounds.bottom); + (int) (outBounds.left + deltaX), + (int) (outBounds.top + deltaY), + (int) (outBounds.right - deltaX), + (int) (outBounds.bottom - deltaY)); } - private float getDecoratedCenterXWithMargins(View child) { + private float getDecoratedCenterWithMargins(View child) { Rect bounds = new Rect(); super.getDecoratedBoundsWithMargins(child, bounds); - return bounds.centerX(); + if (isHorizontal()) { + return bounds.centerX(); + } + return bounds.centerY(); } /** @@ -591,10 +599,10 @@ private void removeAndRecycleOutOfBoundsViews(Recycler recycler) { // Remove items that are out of bounds at the head of the list while (getChildCount() > 0) { View child = getChildAt(0); - float centerX = getDecoratedCenterXWithMargins(child); + float center = getDecoratedCenterWithMargins(child); KeylineRange range = - getSurroundingKeylineRange(currentKeylineState.getKeylines(), centerX, true); - if (isLocOffsetOutOfFillBoundsStart(centerX, range)) { + getSurroundingKeylineRange(currentKeylineState.getKeylines(), center, true); + if (isLocOffsetOutOfFillBoundsStart(center, range)) { removeAndRecycleView(child, recycler); } else { break; @@ -604,10 +612,10 @@ private void removeAndRecycleOutOfBoundsViews(Recycler recycler) { // Remove items that are out of bounds at the tail of the list while (getChildCount() - 1 >= 0) { View child = getChildAt(getChildCount() - 1); - float centerX = getDecoratedCenterXWithMargins(child); + float center = getDecoratedCenterWithMargins(child); KeylineRange range = - getSurroundingKeylineRange(currentKeylineState.getKeylines(), centerX, true); - if (isLocOffsetOutOfFillBoundsEnd(centerX, range)) { + getSurroundingKeylineRange(currentKeylineState.getKeylines(), center, true); + if (isLocOffsetOutOfFillBoundsEnd(center, range)) { removeAndRecycleView(child, recycler); } else { break; @@ -625,8 +633,9 @@ private void removeAndRecycleOutOfBoundsViews(Recycler recycler) { * together. * *
If no keyline is found for the left, the left-most keyline is returned. If no keyline to the
- * right is found, the right-most keyline is returned. This means the {@code location} is outside
- * the bounds of the outer-most keylines.
+ * right is found, the right-most keyline is returned. If the orientation is vertical, the same
+ * goes for top-most and bottom-most keylines respectively. This means the {@code location} is
+ * outside the bounds of the outer-most keylines.
*
* @param location The location along the scrolling axis that should be contained by the returned
* keyline range. This can be either a location in the end-to-end model ({@link Keyline#loc}
@@ -634,62 +643,62 @@ private void removeAndRecycleOutOfBoundsViews(Recycler recycler) {
* @param isOffset true if {@code location} has been offset and should be compared against {@link
* Keyline#locOffset}, false if {@code location} should be compared against {@link
* Keyline#loc}.
- * @return A pair whose first item is the nearest {@link Keyline} before centerX and whose second
- * item is the nearest {@link Keyline} after centerX.
+ * @return A pair whose first item is the nearest {@link Keyline} before center and whose second
+ * item is the nearest {@link Keyline} after center.
*/
private static KeylineRange getSurroundingKeylineRange(
List