Fix the scroll bar thumb jumping a little bit due to lack of smothness on interpolatedIndex

Signed-off-by: Rodrigo Dias Ferreira <rodrigo.dias.rdf@gmail.com>
pull/1550/head
Rodrigo Dias Ferreira 1 year ago
parent e8d5d126b8
commit 31b77d51ba

@ -33,7 +33,7 @@ import kotlin.math.abs
* @return a [Float] in the range [firstItemPosition..nextItemPosition) where nextItemPosition * @return a [Float] in the range [firstItemPosition..nextItemPosition) where nextItemPosition
* is the index of the consecutive item along the major axis. * 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>, visibleItems: List<LazyStateItem>,
crossinline itemSize: LazyState.(LazyStateItem) -> Int, crossinline itemSize: LazyState.(LazyStateItem) -> Int,
crossinline offset: LazyState.(LazyStateItem) -> Int, crossinline offset: LazyState.(LazyStateItem) -> Int,

@ -45,6 +45,7 @@ fun LazyListState.scrollbarState(
) = genericScrollbarState( ) = genericScrollbarState(
itemsAvailable = itemsAvailable, itemsAvailable = itemsAvailable,
visibleItems = { layoutInfo.visibleItemsInfo }, visibleItems = { layoutInfo.visibleItemsInfo },
visibleItemsOnMainAxis = { layoutInfo.visibleItemsInfo },
itemSize = { it.size }, itemSize = { it.size },
offset = { it.offset }, offset = { it.offset },
nextItemOnMainAxis = { first -> layoutInfo.visibleItemsInfo.find { it != first } }, nextItemOnMainAxis = { first -> layoutInfo.visibleItemsInfo.find { it != first } },
@ -67,6 +68,12 @@ fun LazyGridState.scrollbarState(
) = genericScrollbarState( ) = genericScrollbarState(
itemsAvailable = itemsAvailable, itemsAvailable = itemsAvailable,
visibleItems = { layoutInfo.visibleItemsInfo }, 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) }, itemSize = { layoutInfo.orientation.valueOf(it.size) },
offset = { layoutInfo.orientation.valueOf(it.offset) }, offset = { layoutInfo.orientation.valueOf(it.offset) },
nextItemOnMainAxis = { first -> nextItemOnMainAxis = { first ->
@ -100,6 +107,7 @@ fun LazyStaggeredGridState.scrollbarState(
) = genericScrollbarState( ) = genericScrollbarState(
itemsAvailable = itemsAvailable, itemsAvailable = itemsAvailable,
visibleItems = { layoutInfo.visibleItemsInfo }, visibleItems = { layoutInfo.visibleItemsInfo },
visibleItemsOnMainAxis = { layoutInfo.visibleItemsInfo.filter { it.lane == 0 } },
itemSize = { layoutInfo.orientation.valueOf(it.size) }, itemSize = { layoutInfo.orientation.valueOf(it.size) },
offset = { layoutInfo.orientation.valueOf(it.offset) }, offset = { layoutInfo.orientation.valueOf(it.offset) },
nextItemOnMainAxis = { first -> nextItemOnMainAxis = { first ->
@ -128,6 +136,7 @@ fun LazyStaggeredGridState.scrollbarState(
private fun <LazyState : ScrollableState, LazyStateItem> LazyState.genericScrollbarState( private fun <LazyState : ScrollableState, LazyStateItem> LazyState.genericScrollbarState(
itemsAvailable: Int, itemsAvailable: Int,
visibleItems: () -> List<LazyStateItem>, visibleItems: () -> List<LazyStateItem>,
visibleItemsOnMainAxis: () -> List<LazyStateItem>,
itemSize: LazyState.(LazyStateItem) -> Int, itemSize: LazyState.(LazyStateItem) -> Int,
offset: LazyState.(LazyStateItem) -> Int, offset: LazyState.(LazyStateItem) -> Int,
nextItemOnMainAxis: LazyState.(LazyStateItem) -> LazyStateItem?, nextItemOnMainAxis: LazyState.(LazyStateItem) -> LazyStateItem?,
@ -142,11 +151,12 @@ private fun <LazyState : ScrollableState, LazyStateItem> LazyState.genericScroll
if (itemsAvailable == 0) return@snapshotFlow null if (itemsAvailable == 0) return@snapshotFlow null
val visibleItemsInfo = visibleItems() val visibleItemsInfo = visibleItems()
val visibleItemsOnMainAxis = visibleItemsOnMainAxis()
if (visibleItemsInfo.isEmpty()) return@snapshotFlow null if (visibleItemsInfo.isEmpty()) return@snapshotFlow null
val firstIndex = min( val interpolatedIndex = min(
a = interpolateFirstItemIndex( a = interpolateIndex(
visibleItems = visibleItemsInfo, visibleItems = visibleItemsOnMainAxis,
itemSize = itemSize, itemSize = itemSize,
offset = offset, offset = offset,
nextItemOnMainAxis = nextItemOnMainAxis, nextItemOnMainAxis = nextItemOnMainAxis,
@ -154,7 +164,7 @@ private fun <LazyState : ScrollableState, LazyStateItem> LazyState.genericScroll
), ),
b = itemsAvailable.toFloat(), b = itemsAvailable.toFloat(),
) )
if (firstIndex.isNaN()) return@snapshotFlow null if (interpolatedIndex.isNaN()) return@snapshotFlow null
val itemsVisible = visibleItemsInfo.floatSumOf { itemInfo -> val itemsVisible = visibleItemsInfo.floatSumOf { itemInfo ->
itemVisibilityPercentage( itemVisibilityPercentage(
@ -166,7 +176,7 @@ private fun <LazyState : ScrollableState, LazyStateItem> LazyState.genericScroll
} }
val thumbTravelPercent = min( val thumbTravelPercent = min(
a = firstIndex / itemsAvailable, a = interpolatedIndex / itemsAvailable,
b = 1f, b = 1f,
) )
val thumbSizePercent = min( val thumbSizePercent = min(

Loading…
Cancel
Save