Skip to content

Commit

Permalink
Fix the scroll bar thumb jumping a little bit due to lack of smothnes…
Browse files Browse the repository at this point in the history
…s on interpolatedIndex
  • Loading branch information
rodrigodiasferreira committed Jul 15, 2024
1 parent e8d5d12 commit 2fd6bb4
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 : ScrollableState, LazyStateItem> LazyState.interpolateFirstItemIndex(
internal inline fun <LazyState : ScrollableState, LazyStateItem> LazyState.interpolateIndex(
visibleItems: List<LazyStateItem>,
crossinline itemSize: LazyState.(LazyStateItem) -> Int,
crossinline offset: LazyState.(LazyStateItem) -> Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 } },
Expand All @@ -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 ->
Expand Down Expand Up @@ -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 ->
Expand Down Expand Up @@ -128,6 +136,7 @@ fun LazyStaggeredGridState.scrollbarState(
private fun <LazyState : ScrollableState, LazyStateItem> LazyState.genericScrollbarState(
itemsAvailable: Int,
visibleItems: () -> List<LazyStateItem>,
visibleItemsOnMainAxis: () -> List<LazyStateItem>,
itemSize: LazyState.(LazyStateItem) -> Int,
offset: LazyState.(LazyStateItem) -> Int,
nextItemOnMainAxis: LazyState.(LazyStateItem) -> LazyStateItem?,
Expand All @@ -142,19 +151,20 @@ private fun <LazyState : ScrollableState, LazyStateItem> 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,
itemIndex = index,
),
b = itemsAvailable.toFloat(),
)
if (firstIndex.isNaN()) return@snapshotFlow null
if (interpolatedIndex.isNaN()) return@snapshotFlow null

val itemsVisible = visibleItemsInfo.floatSumOf { itemInfo ->
itemVisibilityPercentage(
Expand All @@ -166,7 +176,7 @@ private fun <LazyState : ScrollableState, LazyStateItem> LazyState.genericScroll
}

val thumbTravelPercent = min(
a = firstIndex / itemsAvailable,
a = interpolatedIndex / itemsAvailable,
b = 1f,
)
val thumbSizePercent = min(
Expand Down

0 comments on commit 2fd6bb4

Please sign in to comment.