I want to hide my composable with an animation, bu...
# compose
z
I want to hide my composable with an animation, but I want it to keep its position and size so that other elements arent moved/drawn on top of it.
Modifier.alpha(0f)
works, but I can still click elements in the hidden composable (which makes sense). Is there another way?
s
Maybe animate the alpha so that it fades away, but at the moment when the alpha is 0, also add this https://kotlinlang.slack.com/archives/CJLTWPH7S/p1673314562259549?thread_ts=1673311120.934409&cid=CJLTWPH7S modifier on top, to literally not place the composable, yet still measure it. Could that work?
z
Thanks @Stylianos Gakis! Unfortunately I think Id need to apply that to every composable inside the composable that Im hiding in order for it to work. In my case, hiding a TopBar, and each IconButton inside it is still clickable.
s
If you add this modifier to the TopAppBar instead, and not place it in the first place, I’d assume the children it has also will simply not be placed at all and therefore won’t be clickable. Am I making the wrong assumption here?
z
Thats exactly what I thought as well, but that doesnt seem to be the case - Im still able to click its children!
s
Compose did a little bit of trolling here it may seem
z
Feel free to verify the behavior so that Im not doing something odd on my end of things though 😅 Might be worth to report this as a bug otherwise?
I did manage to solve it and while Ill need to refactor the code, the gist of it is below: Usage is just wrapping my layout in
Keep {}
then using whatever AnimatedVisibility inside the block.
Copy code
@Composable
fun Keep(
    content: @Composable BoxScope.() -> Unit,
) {
    Box(
        modifier = Modifier.keepSize(),
        content = content,
    )
}

private fun Modifier.keepSize(): Modifier {
    return composed {
        var maxSize by remember {
            mutableStateOf(Zero)
        }

        layout { measurable, constraints ->
            val placeable = measurable.measure(constraints)
            val width = placeable.width.coerceAtLeast(maxSize.width)
            val height = placeable.height.coerceAtLeast(maxSize.height)

            maxSize = IntSize(
                width = width,
                height = height,
            )

            layout(
                width = width,
                height = height,
            ) {
                placeable.placeRelative(IntOffset.Zero)
            }
        }
    }
}
It hurts my brain to think that this works great, but I also need a way to limit that to just the height (i.e. this results in a Text retaining its longest width as well).