I have a long screen and I need to send analytics metrics when element is shown on the screen as user scrolls the screen.
I use LazyListState to get information about what element is shown on the screen and I use NestedScrollConnection.onPreScroll to listen scroll.
Everything is OK here except that all elements inside LazyColumn are also custom composables and I need to send metrics when subcomposables of these composables are shown on the screen. Unfortunately now I only send when big parts of the screen are shown. Adding LazyListState to subcomposables is impossible due to nested scrolling restriction.
Do you have any ideas how to detect when each subcomposable of these Composables is shown on the screen?
Here is the content of Composable of this screen:
var shownElements by remember { mutableStateOf(setOf<String>()) }
val scrollState = rememberLazyListState()
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
scrollState.layoutInfo.visibleItemsInfo.forEach {
if (!shownElements.contains(it.key.toString())) {
shownElements = shownElements + (it.key.toString())
sendEvent(ElementShown(it.key.toString()))
}
}
return Offset.Zero
}
}
}
LazyColumn(
modifier = Modifier.nestedScroll(nestedScrollConnection),
state = scrollState,
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
item(key = "TitleAndCardScreen") {
TitleAndCardScreen(
state = state.accountData,
sendEvent = { sendEvent(it) }
)
}
item(key = "BannerAndButtonsScreen") {
BannerAndButtonsScreen(
state = state,
sendEvent = { sendEvent(it) }
)
}
item(key = "PaymentBlock") {
PaymentBlock(
state = paymentBlock,
sendEvent = { sendEvent(it) }
)
}
item(key = "PrivilegeWidgetsScreen") {
PrivilegeWidgetsScreen(
state = state,
onWidgetClicked = { sendEvent(PrivilegeWidgetClicked(it)) })
}
item(key = "InstallmentsBlock") {
InstallmentsBlock(
state = state.installmentsBlockState,
sendEvent = { sendEvent(it) }
)
}
item(key = "ActionButtonsList") {
ActionButtonsList(
state = state,
sendEvent = { sendEvent(it) }
)
}
}