Status Update
Comments
ol...@gmail.com <ol...@gmail.com> #2
Over to Ralston to take a look. I imagine with the new relocation logic it should be fixed?
ae...@google.com <ae...@google.com>
ch...@google.com <ch...@google.com>
ba...@gmail.com <ba...@gmail.com> #3
What is happening here is that the TextField does not know that it is in a scrollable container, and since the keyboard is going to hide the currently focused text, the text field calls View.requestRectangleOnScreen which causes the entire app to pan up, and that clips the top bar.
The Relocation APIs are experimental right now. It is not used in TextField as we are past the alpha stage and can only use stable APIs in TextField. So this bug can only be fixed post 1.0
as...@google.com <as...@google.com> #4
This should be fixed by
I verified that this sample code now works when soft input mode is AdjustResize.
vi...@jobandtalent.com <vi...@jobandtalent.com> #5
an...@google.com <an...@google.com> #6
However as mentioned in the
We think that this api can make it possible for you to configure on what scroll position do you want to end up after the items are inserted or removed.
ba...@gmail.com <ba...@gmail.com> #7
I'm unsure how to reliably keep my scroll position using requestScrollToItem.
I have a feed of items I'm observing with collectAsLazyPagingItems from the paging library, so the items could potentially get updated by a background fetch without knowledge of the UI code, how/when should we call requestScrollToItem then?
And even if I only expect manual invalidations I'm having trouble to make it work, I tried this:
On app reopen, check if there are now more items in the database than the LazyPagingItems.itemCount
If yes calculate how many of them are newer than the currently still visible first item to use as next index in requestScrollToItem
Call requestScrollToItem with the new index, then call invalidate on the PagingSource
If there are enough (more than 130?) new items this seems to work, but if there are only a few new items it seems to (at least sometimes?) snap to double of the calculated index, for example I am scrolled to the newest item, so 0 newer items exist, I background the app, add 20 items, reopen the app, request scroll to index 20, invalidate the pagingsource and end up scrolled to index 40.
Am I conceptually doing something wrong here or is that the intended idea of the api and the double index scroll could be a bug?
an...@google.com <an...@google.com>
an...@google.com <an...@google.com> #8
Example of the usage:
@Composable
fun Demo() {
var items by remember { mutableStateOf(List(100) { 200 + it}) }
LaunchedEffect(Unit) {
delay(5000)
items = List(300) { it }
}
Feed(items)
}
@Composable
fun Feed(list: List<Int>) {
val state = rememberLazyListState()
SideEffect {
val oldFirstItem = state.layoutInfo.visibleItemsInfo.firstOrNull()
if (oldFirstItem != null && list.getOrNull(oldFirstItem.index) != oldFirstItem.key) {
// the key for the firstVisibleItemIndex has been changed
// here we just use indexOfFirst() which will iterate through all
// the items in the list to find the new index. if there is a way
// for you to know what is the new index without doing full iteration
// please use this more efficient way of finding the new index
val newIndex = list.indexOfFirst { it == oldFirstItem.key }
if (newIndex != -1) {
state.requestScrollToItem(newIndex, state.firstVisibleItemScrollOffset)
}
}
}
LazyColumn(state = state) {
items(list, key = { it }) {
Text("Item $it")
}
}
}
Description
LazyList
and other lazy layout Composables lose track of keyed visible items if 130 elements are inserted or removed above them. (Depending on the position in the list, even less than 130 elements trigger the problem.)The attached Compose Desktop sample demonstrates the problem and contains a fixed version
LazyColumn2
which provides akeyToIndexMap
parameter, allowing for custom mappings.Jetpack Compose version: Compose multiplatform 1.4.0-alpha01-dev942
Jetpack Compose component(s) used: Foundation
Kotlin version: 1.8.10
Steps to Reproduce or Code Sample to Reproduce: Sample is attached