From 2aea08364b8e93916a4b984bd8ed622f1ee0f01d Mon Sep 17 00:00:00 2001 From: Rodrigo Dias Ferreira Date: Mon, 15 Jul 2024 16:07:39 -0300 Subject: [PATCH] Bug fix: scroll bar thumb jumping when at the end of the LazyStaggeredList with more than one lane Signed-off-by: Rodrigo Dias Ferreira --- .../scrollbar/LazyScrollbarUtilities.kt | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/LazyScrollbarUtilities.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/LazyScrollbarUtilities.kt index 57e567b5d..b7e610695 100644 --- a/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/LazyScrollbarUtilities.kt +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/LazyScrollbarUtilities.kt @@ -74,6 +74,19 @@ internal fun itemVisibilityPercentage( viewportEndOffset: Int, ): Float { if (itemSize == 0) return 0f + // TODO: Workaround due to issue b/353143657, monitor if compose team will agree it's an issue + // and fix it, if so, below safeguard probably can be removed + if ( + isItemOutOfViewport( + itemSize = itemSize, + itemStartOffset = itemStartOffset, + viewportStartOffset = viewportStartOffset, + viewportEndOffset = viewportEndOffset, + ) + ) { + return 0f + } + val itemEnd = itemStartOffset + itemSize val startOffset = when { itemStartOffset > viewportStartOffset -> 0 @@ -86,3 +99,28 @@ internal fun itemVisibilityPercentage( val size = itemSize.toFloat() return (size - startOffset - endOffset) / size } + +private fun isItemOutOfViewport( + itemSize: Int, + itemStartOffset: Int, + viewportStartOffset: Int, + viewportEndOffset: Int, +) = isItemBeforeViewport( + itemSize = itemSize, + itemStartOffset = itemStartOffset, + viewportStartOffset = viewportStartOffset, +) || isItemAfterViewport( + itemStartOffset = itemStartOffset, + viewportEndOffset = viewportEndOffset, +) + +private fun isItemBeforeViewport( + itemSize: Int, + itemStartOffset: Int, + viewportStartOffset: Int, +) = (viewportStartOffset - itemStartOffset) > itemSize + +private fun isItemAfterViewport( + itemStartOffset: Int, + viewportEndOffset: Int, +) = itemStartOffset > viewportEndOffset