I’m trying to toggle a state based on some offset ...
# compose
r
I’m trying to toggle a state based on some offset calculations when observing the visible items in a
LazyColumn
. This is kind of the code I’m trying to achieve it with. Problem though is that
snapshotFlow
is dropping emits when flinging the list fast.
Copy code
LaunchedEffect(Unit) {                                                        
     snapshotFlow { listState.layoutInfo.visibleItemsInfo }                   
         .mapNotNull { it.firstOrNull { it.key == KEY_BIG_TITLE } }           
         .onEach { showTopBar = it.offset < 0}                                
         .collect()                                                           
 }
Dropped emits with this solution makes it a deal breaker in my case. Does someone have any advice on an alternative way of doing it?
c
Have you tried using derivedStateOf instead of snapshotFlow?
r
I have, with similar results however in that case I’m not sure why as with the snapshotFlow I can pretty easily reproduce the “dropped emits”. I might give that a go again.
a
Can you calculate the index for the item you care about, and then use
firstVisibleItemIndex
and
firstVisibleItemScrollOffset
? That will probably be a more robust solution in general, since right now you’re assuming that at some point you’ll see the
KEY_BIG_TITLE
item. Maybe you’re super far past that item, then your device rotates and your Activity is recreated, and your list scroll position is restored far past the title.
r
Maybe you’re super far past that item, then your device rotates
yes that feels like an issue. Your suggestion sounds good! I’ll give that a go! 🙏
s
Layout info is not guaranteed to be sequential. If you drop a frame, measure will skip over some content to compensate for scroll and that content won't be reflected in layout info. I'd consider calculating item index and check if the list have scroll past. Alternative solution here will be to run side effect in the item itself, as the skipped item is still composed and measured.