From 2fd6bb43573cd645265ba04d865d2ed42f08e97a Mon Sep 17 00:00:00 2001 From: Rodrigo Dias Ferreira Date: Mon, 15 Jul 2024 18:55:56 -0300 Subject: [PATCH] Fix the scroll bar thumb jumping a little bit due to lack of smothness on interpolatedIndex --- .../scrollbar/LazyScrollbarUtilities.kt | 2 +- .../component/scrollbar/ScrollbarExt.kt | 20 ++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) 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..781fede62c 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 @@ -33,7 +33,7 @@ import kotlin.math.abs * @return a [Float] in the range [firstItemPosition..nextItemPosition) where nextItemPosition * is the index of the consecutive item along the major axis. * */ -internal inline fun LazyState.interpolateFirstItemIndex( +internal inline fun LazyState.interpolateIndex( visibleItems: List, crossinline itemSize: LazyState.(LazyStateItem) -> Int, crossinline offset: LazyState.(LazyStateItem) -> Int, 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 849e18d3e8..bfceb3a3cf 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 @@ -45,6 +45,7 @@ fun LazyListState.scrollbarState( ) = genericScrollbarState( itemsAvailable = itemsAvailable, visibleItems = { layoutInfo.visibleItemsInfo }, + visibleItemsOnMainAxis = { layoutInfo.visibleItemsInfo }, itemSize = { it.size }, offset = { it.offset }, nextItemOnMainAxis = { first -> layoutInfo.visibleItemsInfo.find { it != first } }, @@ -67,6 +68,12 @@ fun LazyGridState.scrollbarState( ) = genericScrollbarState( itemsAvailable = itemsAvailable, visibleItems = { layoutInfo.visibleItemsInfo }, + visibleItemsOnMainAxis = { + 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 -> @@ -100,6 +107,7 @@ fun LazyStaggeredGridState.scrollbarState( ) = genericScrollbarState( itemsAvailable = itemsAvailable, visibleItems = { layoutInfo.visibleItemsInfo }, + visibleItemsOnMainAxis = { layoutInfo.visibleItemsInfo.filter { it.lane == 0 } }, itemSize = { layoutInfo.orientation.valueOf(it.size) }, offset = { layoutInfo.orientation.valueOf(it.offset) }, nextItemOnMainAxis = { first -> @@ -128,6 +136,7 @@ fun LazyStaggeredGridState.scrollbarState( private fun LazyState.genericScrollbarState( itemsAvailable: Int, visibleItems: () -> List, + visibleItemsOnMainAxis: () -> List, itemSize: LazyState.(LazyStateItem) -> Int, offset: LazyState.(LazyStateItem) -> Int, nextItemOnMainAxis: LazyState.(LazyStateItem) -> LazyStateItem?, @@ -142,11 +151,12 @@ private fun LazyState.genericScroll if (itemsAvailable == 0) return@snapshotFlow null val visibleItemsInfo = visibleItems() + val visibleItemsOnMainAxis = visibleItemsOnMainAxis() if (visibleItemsInfo.isEmpty()) return@snapshotFlow null - val firstIndex = min( - a = interpolateFirstItemIndex( - visibleItems = visibleItemsInfo, + val interpolatedIndex = min( + a = interpolateIndex( + visibleItems = visibleItemsOnMainAxis, itemSize = itemSize, offset = offset, nextItemOnMainAxis = nextItemOnMainAxis, @@ -154,7 +164,7 @@ private fun LazyState.genericScroll ), b = itemsAvailable.toFloat(), ) - if (firstIndex.isNaN()) return@snapshotFlow null + if (interpolatedIndex.isNaN()) return@snapshotFlow null val itemsVisible = visibleItemsInfo.floatSumOf { itemInfo -> itemVisibilityPercentage( @@ -166,7 +176,7 @@ private fun LazyState.genericScroll } val thumbTravelPercent = min( - a = firstIndex / itemsAvailable, + a = interpolatedIndex / itemsAvailable, b = 1f, ) val thumbSizePercent = min(