Skip to content

Commit 6b263fa

Browse files
imhappipaulfthomas
authored andcommitted
[Carousel] Fix carousel spamming view re-binding
PiperOrigin-RevId: 651470722
1 parent 4abc9c6 commit 6b263fa

File tree

1 file changed

+27
-16
lines changed

1 file changed

+27
-16
lines changed

lib/java/com/google/android/material/carousel/CarouselLayoutManager.java

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -431,19 +431,26 @@ public void onLayoutCompleted(State state) {
431431
private void addViewsStart(Recycler recycler, int startPosition) {
432432
float start = calculateChildStartForFill(startPosition);
433433
for (int i = startPosition; i >= 0; i--) {
434-
ChildCalculations calculations = makeChildCalculations(recycler, start, i);
435-
if (isLocOffsetOutOfFillBoundsStart(calculations.offsetCenter, calculations.range)) {
434+
float center = addEnd(start, currentKeylineState.getItemSize() / 2F);
435+
KeylineRange range =
436+
getSurroundingKeylineRange(currentKeylineState.getKeylines(), center, false);
437+
438+
float offsetCenter = calculateChildOffsetCenterForLocation(center, range);
439+
if (isLocOffsetOutOfFillBoundsStart(offsetCenter, range)) {
436440
break;
437441
}
438442
start = addStart(start, currentKeylineState.getItemSize());
439443

440444
// If this child's start is beyond the end of the container, don't add the child but continue
441445
// to loop so we can eventually get to children that are within bounds.
442-
if (isLocOffsetOutOfFillBoundsEnd(calculations.offsetCenter, calculations.range)) {
446+
if (isLocOffsetOutOfFillBoundsEnd(offsetCenter, range)) {
443447
continue;
444448
}
449+
View child = recycler.getViewForPosition(i);
450+
measureChildWithMargins(child, 0, 0);
445451
// Add this child to the first index of the RecyclerView.
446-
addAndLayoutView(calculations.child, /* index= */ 0, calculations);
452+
addAndLayoutView(
453+
child, /* index= */ 0, new ChildCalculations(child, center, offsetCenter, range));
447454
}
448455
}
449456

@@ -476,19 +483,26 @@ private void addViewAtPosition(@NonNull Recycler recycler, int startPosition, in
476483
private void addViewsEnd(Recycler recycler, State state, int startPosition) {
477484
float start = calculateChildStartForFill(startPosition);
478485
for (int i = startPosition; i < state.getItemCount(); i++) {
479-
ChildCalculations calculations = makeChildCalculations(recycler, start, i);
480-
if (isLocOffsetOutOfFillBoundsEnd(calculations.offsetCenter, calculations.range)) {
486+
float center = addEnd(start, currentKeylineState.getItemSize() / 2F);
487+
KeylineRange range =
488+
getSurroundingKeylineRange(currentKeylineState.getKeylines(), center, false);
489+
490+
float offsetCenter = calculateChildOffsetCenterForLocation(center, range);
491+
if (isLocOffsetOutOfFillBoundsEnd(offsetCenter, range)) {
481492
break;
482493
}
483494
start = addEnd(start, currentKeylineState.getItemSize());
484495

485496
// If this child's end is beyond the start of the container, don't add the child but continue
486497
// to loop so we can eventually get to children that are within bounds.
487-
if (isLocOffsetOutOfFillBoundsStart(calculations.offsetCenter, calculations.range)) {
498+
if (isLocOffsetOutOfFillBoundsStart(offsetCenter, range)) {
488499
continue;
489500
}
501+
View child = recycler.getViewForPosition(i);
502+
measureChildWithMargins(child, 0, 0);
490503
// Add this child to the last index of the RecyclerView
491-
addAndLayoutView(calculations.child, /* index= */ -1, calculations);
504+
addAndLayoutView(
505+
child, /* index= */ -1, new ChildCalculations(child, center, offsetCenter, range));
492506
}
493507
}
494508

@@ -562,7 +576,7 @@ private ChildCalculations makeChildCalculations(Recycler recycler, float start,
562576
KeylineRange range =
563577
getSurroundingKeylineRange(currentKeylineState.getKeylines(), center, false);
564578

565-
float offsetCenter = calculateChildOffsetCenterForLocation(child, center, range);
579+
float offsetCenter = calculateChildOffsetCenterForLocation(center, range);
566580
return new ChildCalculations(child, center, offsetCenter, range);
567581
}
568582

@@ -889,13 +903,12 @@ private float calculateChildStartForFill(int startPosition) {
889903
/**
890904
* Remaps and returns the child's offset center from the end-to-end layout model.
891905
*
892-
* @param child the child to calculate the offset for
893906
* @param childCenterLocation the center of the child in the end-to-end layout model
894907
* @param range the keyline range that the child is currently between
895908
* @return the location along the scroll axis where the child should be located
896909
*/
897910
private float calculateChildOffsetCenterForLocation(
898-
View child, float childCenterLocation, KeylineRange range) {
911+
float childCenterLocation, KeylineRange range) {
899912
float offsetCenter =
900913
lerp(
901914
range.leftOrTop.locOffset,
@@ -915,11 +928,9 @@ private float calculateChildOffsetCenterForLocation(
915928
// Calculate how far past the nearest keyline (either the first or last keyline) this item
916929
// has scrolled in the end-to-end layout. Then use that value calculate what would be a
917930
// Keyline#locOffset.
918-
LayoutParams lp = (LayoutParams) child.getLayoutParams();
919-
float marginMask = orientationHelper.getMaskMargins(lp) / currentKeylineState.getItemSize();
920931
float outOfBoundOffset =
921932
(childCenterLocation - range.rightOrBottom.loc)
922-
* (1F - range.rightOrBottom.mask + marginMask);
933+
* (1F - range.rightOrBottom.mask);
923934
offsetCenter += outOfBoundOffset;
924935
}
925936

@@ -977,7 +988,7 @@ private void updateChildMaskForLocation(
977988

978989
RectF maskRect = orientationHelper.getMaskRect(childHeight, childWidth, maskHeight, maskWidth);
979990

980-
float offsetCenter = calculateChildOffsetCenterForLocation(child, childCenterLocation, range);
991+
float offsetCenter = calculateChildOffsetCenterForLocation(childCenterLocation, range);
981992
float maskedTop = offsetCenter - (maskRect.height() / 2F);
982993
float maskedBottom = offsetCenter + (maskRect.height() / 2F);
983994
float maskedLeft = offsetCenter - (maskRect.width() / 2F);
@@ -1508,7 +1519,7 @@ private float offsetChild(View child, float startOffset, float halfItemSize, Rec
15081519
float center = addEnd(startOffset, halfItemSize);
15091520
KeylineRange range =
15101521
getSurroundingKeylineRange(currentKeylineState.getKeylines(), center, false);
1511-
float offsetCenter = calculateChildOffsetCenterForLocation(child, center, range);
1522+
float offsetCenter = calculateChildOffsetCenterForLocation(center, range);
15121523

15131524
// Offset the child so its center is at offsetCenter
15141525
super.getDecoratedBoundsWithMargins(child, boundsRect);

0 commit comments

Comments
 (0)