In a few places in the app, I have a mechanism to ...
# compose
k
In a few places in the app, I have a mechanism to scroll to a component on the screen. The scroll is being made when, in the state, an enum value appears. To scroll to the component, I need to know its position. Because I would like to create a generic component that will let me reuse this mechanism in various places in the app, I came up with the idea to create a custom
Modifier
that, under the hood, uses
onGloballyPositioned
and saves the
y
value in the map with the corresponding enum value (code in Thread). Is there a better way to achieve that? Do you see any issues with this solution?
Copy code
@Composable
fun <T: Enum<*>> ScrollToContainer(
    scrollState: ScrollState,
    scrollTo: T?,
    onScrolledTo: (T) -> Unit,
    content: @Composable ScrollToContainerScope<T>.() -> Unit,
) {
    val map = remember { mutableStateMapOf<T, Int>() }
    val scope = remember { ScrollToContainerScope(map) }
    LaunchedEffect(key1 = scrollTo) {
        if (scrollTo != null) {
            val position = map[scrollTo]
            if (position != null) {
                scrollState.animateScrollTo(position)
                onScrolledTo(scrollTo)
            } else {
                error("tag not found: $scrollTo")
            }
        }
    }
    content(scope)
}

class ScrollToContainerScope<T: Enum<*>>(private val map: MutableMap<T, Int>) {

    fun Modifier.markWithTag(tag: T): Modifier =
        onGloballyPositioned {
            map[tag] = it.positionInParent().y.toInt()
        }
}
a
BringIntoViewRequester is what you want.
k
Neat, I wasn’t aware of this mechanism, thank you