How can I disable clipping with `AnimatedVisibilit...
# compose
r
How can I disable clipping with
AnimatedVisibility
? A recent update to compose seems to have enabled clipping each item that appears by default, which has caused a UI regression in my app. Docs suggest adding
.using(SizeTransform(clip = false))
to the transitionSpec, but AnimatedVisibility doesn't take a transitionSpec, and my animations are actually applied by a series of
Modifier.animateEnterExit(...)
on each item.
d
What type of enter/exit transition are you using?
r
@Doris Liu I'm using a
slideInVertically
with a large y offset. The desired effect is that the content slides up the screen into its final resting place. This is how it behaved before. Now, the content is clipped to its bounding box,.
d
Do you know which version of compose started having this issue? Could you also file an issue, with a code snippet to repro please? 🙏
b
@Doris Liu I have a similar issue, where applying SizeTransform(clip=false) doesn't remove the clipping.. (Although this is not a regression issue for me, using compose 2024.09.00 bom) Do you have any idea how to improve this animation to remove clipping?
Copy code
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun AnimatedText(
    text: String,
    modifier: Modifier = Modifier,
    style: TextStyle = LocalTextStyle.current,
    transitionSpec: AnimatedContentTransitionScope<Char>.() -> ContentTransform = {
        (if (targetState > initialState) {
            (slideInVertically { -it } + fadeIn()) togetherWith (slideOutVertically { it } + fadeOut())
        } else {
            (slideInVertically { it } + fadeIn()) togetherWith (slideOutVertically { -it } + fadeOut())
        }).using(
            SizeTransform(clip = false)
        )
    }
) {
    FlowRow(
        modifier = modifier
            .animateContentSize()
            // merge all text parts into one row so accessibility services can read it as one value
            .clearAndSetSemantics { contentDescription = text },
        horizontalArrangement = Arrangement.Start,
    ) {
        text.forEachIndexed { charIndex, character ->
            val transition = updateTransition(targetState = character, label = "CharacterTransition")
            transition.AnimatedContent(
                contentAlignment = Alignment.TopStart,
                transitionSpec = transitionSpec,
            ) { characterState ->
                Text(
                    text = characterState.toString(),
                    style = style
                )
            }
        }
    }
}
d
The clipping here probably comes from
Modifier.animateContentSize
.
b
That was it, thanks! Somewhat relevant, why exactly can't animateContentSize allow not clipping? i.e forking animateContentSize and removing clipToBounds call simply works (see code here https://gist.github.com/alashow/09152d76c090667015faafa2f8ad5647).. so why can't that offered via animateContentSize? Is clipToBounds always to applied to fix some corner cases maybe? Still doesn't explain why it's always applied without option to remove
d
why exactly can't animateContentSize allow not clipping?
animatedContentSize
modifier is a clipBounds animation, if you remove the clipping you'll see no clipping, the content just jumps from small to large. In that case, you will only get an animated effect coming from the gradual size change, but visually it won't look great. Have you tried animating the content size from small to large?
b
> Have you tried animating the content size from small to large? Not sure what you mean? My use case for animatedContentSize without clipping was that I had Row (FlowRow to be exact) with TextButton inside. When animateContentSize is applied to Row, click indication of TextButton would get clipped. animateContentSize just adds a nice transition for my use case so just removing the clipping fixed the issue for me, with no visual issues. My case of TextButton might be unique too*, not sure any other cases doesn't need clipping for animateContentSize. It might be more unique case because I also have
.graphicsLayer(translationX = with(density) { -12.toPx() })
applied to TextButton so it would appear left aligned with other elements (since textbutton has internal padding..)
Kapture 2024-10-21 at 17.51.16.mp4
vs with clip
Just realized with clipping animation looks much different 😄
310 Views