There is no out-of-the-box functionality to suppor...
# compose
o
There is no out-of-the-box functionality to support insertion/deletion of elements in large lazy containers (such as
LazyColumn
), right? Background: Demos such as
compose/foundation/demos/LazyColumnDragAndDropDemo.kt
replace the entire list when adding/removing an element. This is less than ideal for really large lists which are backed by a fully synchronized data source (i.e. no such thing as "refresh"). Suggested solution in 🧵.
✅ 1
To deal with large editable lists, I'm considering the following: Create lazy items like so (vertical scenario, from top to bottom): • Insert a single placeholder Composable with a height calculated from the sum of all element placeholders above the visible range of elements, reserving scroll space. • Insert as many items as necessary for the range of visible elements. • Insert a single placeholder Composable like above, but this time for all items below the visible range. Update as indicated by
LazyListState
. Rebuild the above on insertions/deletions (the number of visible items is low), basically replacing the (small) item list. Does that make sense? Better ideas?
a
How big is the list? I had an app with ~1000 items in an immutable list sometimes updating 60 fps. What about using
mutableStateListOf
?
o
Oh, my use-case is a very generic scenario, so the list is potentially arbitrarily big. Could be hundreds of thousands, or millions of elements.
Composing a large number of invisible placeholders would probably put a pretty high load on the slot table.
a
The docs say that only visible elements are composed - https://developer.android.com/jetpack/compose/lists#lazy But I will stay subscribed to hear more solutions. 😀
o
Interesting. Surely elements not seen yet (in a top-to-bottom scenario those at the bottom) won't be composed once the lazy container detects that they are outside of the viewport. Not so sure regarding elements above the viewport. At least they'd have to be measured to properly size the scrollbar. And my list can be really large, yet interaction could start at the bottom, displaying only the last couple of elements with potentially millions of invisible elements above. 🙃
s
I don't really understand your problem. The demo updates the source while you are dragging the item - I guess you want to update the source only when the drag is ended?
o
Doesn't really matter whether in-flight updates are included or not. It's not just about drag&drop. It is more generally about inserting/deleting elements in a really large list.
t
Items above the viewport are not needed for the scrollbar. Instead, the average item size of the currently shown items is used to approximate the scrollbar size. The LazyColumn really only measures and draws the visible items. (relevant ancient issue regarding the scrollbars: https://github.com/JetBrains/compose-jb/issues/181)
o
That's interesting. I still need to check that behavior. I'll report back here.
@Tobias Suchalla It seems like you are entirely correct: Compose's lazy lists can perfectly deal with a small viewport into large lists, composing only the visible items and apparently guessing measurements for items outside the viewport. That's exactly what I need, and much more than I expected. Yay! 🚀K🎉
d
What do you mean by guessing?
o
If you do not measure the elements outside the viewport, you have to guess their size to properly size the scrollbar (vertically: height of visible elements / height of visible+invisible elements).
d
Ahhhh I see, fair enough