timeline : improve jumpTo precision (introducing animateScrollToItemCenter)
This commit is contained in:
parent
88e01e7c2e
commit
adc03c9676
14 changed files with 102 additions and 86 deletions
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
package io.element.android.libraries.designsystem.utils
|
||||
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.lazy.LazyListLayoutInfo
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
|
|
@ -35,3 +37,38 @@ fun LazyListState.isScrollingUp(): Boolean {
|
|||
}
|
||||
}.value
|
||||
}
|
||||
|
||||
suspend fun LazyListState.animateScrollToItemCenter(index: Int) {
|
||||
fun LazyListLayoutInfo.containerSize(): Int {
|
||||
return if (orientation == Orientation.Vertical) {
|
||||
viewportSize.height
|
||||
} else {
|
||||
viewportSize.width
|
||||
} - beforeContentPadding - afterContentPadding
|
||||
}
|
||||
|
||||
fun LazyListLayoutInfo.resolveItemOffsetToCenter(index: Int): Int? {
|
||||
val itemInfo = visibleItemsInfo.firstOrNull { it.index == index } ?: return null
|
||||
val containerSize = containerSize()
|
||||
val itemSize = itemInfo.size
|
||||
return if (itemSize > containerSize) {
|
||||
itemSize - containerSize / 2
|
||||
} else {
|
||||
-(containerSize() - itemInfo.size) / 2
|
||||
}
|
||||
}
|
||||
|
||||
// await for the first layout.
|
||||
scroll { }
|
||||
layoutInfo.resolveItemOffsetToCenter(index)?.let { offset ->
|
||||
// Item is already visible, just scroll to center.
|
||||
animateScrollToItem(index, offset)
|
||||
return
|
||||
}
|
||||
// Item is not visible, jump to it...
|
||||
scrollToItem(index)
|
||||
// and then adjust according to the actual item size.
|
||||
layoutInfo.resolveItemOffsetToCenter(index)?.let { offset ->
|
||||
animateScrollToItem(index, offset)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue