Travis Griggs
05/07/2024, 7:08 PMTravis Griggs
05/07/2024, 7:09 PMval LazyListItemInfo.endOffset get() = offset + size
suspend fun LazyListState.animateMakeVisible(target: Int) {
// filter out out-of-range targets
if (target !in 0 until layoutInfo.totalItemsCount) {
return
}
// easy branch first, is our target "above" visible range, if so scroll to it
val firstFullIndex = when (firstVisibleItemScrollOffset) {
0 -> firstVisibleItemIndex
else -> firstVisibleItemIndex + 1
}
if (target < firstFullIndex) {
return animateScrollToItem(target)
}
// heftier branch, as long as the last item isn't visble, keep scrolling by the last items size until we arrive out our target
while ((layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: target) < target) {
layoutInfo.visibleItemsInfo.lastOrNull()?.let { lastItem ->
scrollBy(lastItem.size.toFloat()) // don't animate this one, that creates a comical effect :D
}
}
// and finally do any sub-item adjustment we need
layoutInfo.visibleItemsInfo.lastOrNull()?.let { lastItem ->
if (lastItem.index == target) {
animateScrollBy((lastItem.endOffset - layoutInfo.viewportEndOffset).toFloat())
}
}
}
Zach Klippenstein (he/him) [MOD]
05/07/2024, 8:18 PMTravis Griggs
05/07/2024, 8:26 PMval after = WindowInsets.imeAnimationTarget.getBottom(LocalDensity.current)
val before = WindowInsets.imeAnimationSource.getBottom(LocalDensity.current)
val listLayout by remember { derivedStateOf { scrollState.layoutInfo } }
var visibleIndex by remember { mutableStateOf<Int?>(null) }
LaunchedEffect(after, before, listLayout.viewportEndOffset, visibleIndex) {
if (after == before) {
visibleIndex?.let { index ->
scrollState.animateMakeVisible(index)
}
}
}
Maybe I need to shift back to bringIntoView requestors; I had tried to link them to the focusChanged, but perhaps it's an ordering issue. The above seems to be pretty reliable at triggering "the keyboard is done now, fix things so they're visible". I'll retry and report back.Zach Klippenstein (he/him) [MOD]
05/07/2024, 8:30 PMTravis Griggs
05/07/2024, 8:37 PMTravis Griggs
05/07/2024, 9:07 PMZach Klippenstein (he/him) [MOD]
05/08/2024, 12:14 AM