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 57e567b5d0..b7e6106954 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 diff --git a/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ScrollbarExt.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ScrollbarExt.kt index 3fcc8f2c0d..051c8b5ab1 100644 --- a/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ScrollbarExt.kt +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ScrollbarExt.kt @@ -115,7 +115,10 @@ fun LazyGridState.scrollbarState( val firstIndex = min( a = interpolateFirstItemIndex( - visibleItems = visibleItemsInfo, + visibleItems = when (layoutInfo.orientation) { + Orientation.Vertical -> layoutInfo.visibleItemsInfo.filter { it.row == 0 } + Orientation.Horizontal -> layoutInfo.visibleItemsInfo.filter { it.column == 0 } + }, itemSize = { layoutInfo.orientation.valueOf(it.size) }, offset = { layoutInfo.orientation.valueOf(it.offset) }, nextItemOnMainAxis = { first -> @@ -189,7 +192,7 @@ fun LazyStaggeredGridState.scrollbarState( val firstIndex = min( a = interpolateFirstItemIndex( - visibleItems = visibleItemsInfo, + visibleItems = layoutInfo.visibleItemsInfo.filter { it.lane == 0 }, itemSize = { layoutInfo.orientation.valueOf(it.size) }, offset = { layoutInfo.orientation.valueOf(it.offset) }, nextItemOnMainAxis = { first ->