Colton Idle
07/05/2022, 12:03 AMshikasd
07/05/2022, 12:08 AMColton Idle
07/05/2022, 12:12 AMshikasd
07/05/2022, 12:13 AMgetMoreInfo
will be called with the same items on each measure, so most likely you want a derived stateshikasd
07/05/2022, 12:14 AMLeaves me with a broken code
Oh well, there's
.value
missing afterwardsColton Idle
07/05/2022, 12:14 AMshikasd
07/05/2022, 12:14 AMColton Idle
07/05/2022, 12:14 AMshikasd
07/05/2022, 12:15 AMBen Trengrove [G]
07/05/2022, 12:16 AMvisibleItems
in your composition? snapshotFlow
might be better here, you could avoid composition altogether. Just move everything into the LaunchedEffect
Similar to https://developer.android.com/jetpack/compose/side-effects#snapshotFlowColton Idle
07/05/2022, 12:18 AMval visibleItems = remember { derivedStateOf { listState.layoutInfo } }.value.visibleItemsInfo.map {
Log.e("TEST", "ITEM VISIBLE!")
it.index
}
ITEM VISIBILE just keeps repeating forever... even when I'm not scrolling. Is that expected?shikasd
07/05/2022, 12:19 AMColton Idle
07/05/2022, 12:21 AMval visibleItems = remember {
derivedStateOf {
listState.layoutInfo.visibleItemsInfo.map {
Log.e("TEST", "ITEM VISIBLE!")
it.index
}
}
}
?shikasd
07/05/2022, 12:21 AMshikasd
07/05/2022, 12:21 AMBen Trengrove [G]
07/05/2022, 12:24 AMLaunchedEffect(listState) {
snapshotFlow { listState.layoutInfo.visibleItemsInfo }
.map { it.index }
.distinctUntilChanged()
.collect { it.forEach { viewModel... } }
}
If you want to try snapshotFlow. It's a moot point if you are using visibleItems for something after the LaunchedEffect but if you are just using it to notify the viewModel then you can avoid the recomposition you'd be causing by switching to snapshotFlowColton Idle
07/05/2022, 12:25 AMval visibleItems = remember {
derivedStateOf {
listState.layoutInfo.visibleItemsInfo.map {
Log.e("TEST", "ITEM VISIBLE")
it.index
}
}
}
LaunchedEffect(
key1 = visibleItems, block = {
visibleItems.value.forEach {
Log.e("TEST", "Getting more info for: $it")
viewModel.getMoreInfoFor(it)
}
})
ITEM VISIBLE is called like 6 times, but I only get more info for the first items on the screen (3 items). No updates while I scroll.Colton Idle
07/05/2022, 12:28 AMBen Trengrove [G]
07/05/2022, 12:32 AMLaunchedEffect(listState) {
snapshotFlow { listState.layoutInfo.visibleItemsInfo.map { it.index } }
.distinctUntilChanged()
.collect {}
}
Also just writing code in slack sorry, it's probably that insteadColton Idle
07/05/2022, 12:33 AMshikasd
07/05/2022, 12:34 AMsnapshotFlow
solution more, but if you want to make derived state work, just make sure you read it in composition. You want LaunchedEffect(visibleItems.value)
or just use val visibleItems by remember { ... }
Colton Idle
07/05/2022, 12:38 AMColton Idle
07/05/2022, 12:39 AMColton Idle
07/05/2022, 12:40 AMLaunchedEffect(listState) {
snapshotFlow { listState.layoutInfo.visibleItemsInfo.map { it.index } }
.distinctUntilChanged()
.collect { indexes ->
indexes.forEach {
viewModel.getMoreInfoFor(it)
}
}
}
shikasd
07/05/2022, 12:40 AMBen Trengrove [G]
07/05/2022, 12:40 AMLaunchedEffect(listState) {
snapshotFlow { listState.layoutInfo.visibleItemsInfo }
.distinctUntilChanged()
.collect {
it.forEach {
viewMode.getMoreInfo(it.index)
}
}
}
Colton Idle
07/05/2022, 12:49 AMBen Trengrove [G]
07/05/2022, 12:50 AMColton Idle
07/05/2022, 12:50 AMBen Trengrove [G]
07/05/2022, 12:52 AMColton Idle
07/05/2022, 12:53 AMval visibleItems = remember {
derivedStateOf {
listState.layoutInfo.visibleItemsInfo.map {
Log.e("TEST", "ITEM VISIBLE")
it.index
}
}
}
LaunchedEffect(
key1 = visibleItems.value, block = {
visibleItems.value.forEach {
Log.e("TEST", "Getting more info for: $it")
viewModel.getMoreInfoFor(it)
}
})
@shikasd this is the code that I have that works with "your" derivedState approach. This also does not lag in release builds 🦜
What I did find interesting though is that my column has 20 items total. 3 items fit on the screen typically... but
ITEM VISIBLE shows up 60 times in the logs just when i scroll by 1px. Still seems like something inefficient is going on... but it doesn't actually seem to affect the perf since it has parity with one of the approaches suggested by ben.Ben Trengrove [G]
07/05/2022, 1:04 AMFrancesc
07/05/2022, 1:07 AMvisibleItemsInfo
has a list of LazyListItemInfo
which, among other things, has the item offset in pixels, so any scroll will trigger an update because the object has changedColton Idle
07/05/2022, 1:08 AMLaunchedEffect(listState) {
snapshotFlow { listState.layoutInfo.visibleItemsInfo.map { it.index } }
.distinctUntilChanged()
.collect { indexes ->
indexes.forEach {
viewModel.getMoreInfoFor(it)
}
}
}
Ben Trengrove [G]
07/05/2022, 1:09 AMFrancesc
07/05/2022, 1:09 AMColton Idle
07/05/2022, 1:11 AMpepos
07/05/2022, 1:12 AMFrancesc
07/05/2022, 1:12 AMindex
property in that case for the lazy list info as wellpepos
07/05/2022, 1:12 AMColton Idle
07/05/2022, 1:14 AMviewModel.getMoreInfoForItemWithId(item.id)
pepos
07/05/2022, 1:17 AMitem { }
block which you have access to the item directlypepos
07/05/2022, 1:17 AMFrancesc
07/05/2022, 1:18 AMpepos
07/05/2022, 1:20 AMremember(item.id)
or LaunchEffectFrancesc
07/05/2022, 1:21 AMpepos
07/05/2022, 1:24 AMFrancesc
07/05/2022, 1:25 AMBen Trengrove [G]
07/05/2022, 1:26 AMpepos
07/05/2022, 1:26 AM