https://kotlinlang.org logo
#compose
Title
# compose
d

Dan Peluso

01/26/2023, 9:09 PM
I'm having some issues using the
Popup
composable with the
AnimatedVisibility
composable. I am using
PopupPositionProvider
to determine where to anchor my popup in relation to the parent, and only rendering the popup inside of a conditional statement. My issue is, when I replace my standard
if(...)
with the
AnimatedVisibility
composable as the parent of my popup, the position provider stops working. I think this is because the parent has changed from the original ( I was using
Box
) to the
AnimatedVisibility
composable. Is there a way I can guarantee the
AnimatedVisibility
parent to fit the same size parameters as its own parent? I would think that adding some IntrinsicSize modification or a fillMaxSize param would fix this, but the popup still is not positioned where I want it to be
Copy code
here is the one that I would expect to behave the same as the if, but breaks

fun CustomTooltip(
    parentComposable: @Composable () -> Unit,
    tooltipContent: @Composable () -> Unit,
    showTooltip: Boolean,
    popupPositionProvider: CustomPopupPositionProvider,
    modifier: Modifier = Modifier
) {
    Box(modifier) {
        parentComposable()
        AnimatedVisibility(visible = showTooltip) {
            Popup(popupPositionProvider = popupPositionProvider) {
                tooltipContent()
            }
        }
    }
}


here is the original that behaves properly and positions to the correct side of the parent composable

fun CustomTooltip(
    parentComposable: @Composable () -> Unit,
    tooltipContent: @Composable () -> Unit,
    showTooltip: Boolean,
    popupPositionProvider: CustomPopupPositionProvider,
    modifier: Modifier = Modifier
) {
    Box(modifier) {
        parentComposable()
        if (showTooltip) {
            Popup(popupPositionProvider = popupPositionProvider) {
                tooltipContent()
            }
        }
    }
}
how the bottom one renders
how the top one renders (the expected behavior)
a

Albert Chang

01/27/2023, 1:17 AM
Since
Popup
renders its content in a separate window,
AnimatedVisibility
outside
Popup
has no effect on the content of the popup. If you want to animate the content, put
AnimatedVisibility
inside
Popup
.
d

Dan Peluso

01/30/2023, 4:12 PM
Hm, I tried doing that but had an issue where I cannot get the animated visibility to behave as expected. I think it has something to do with how the popup only will appear in a conditional field, and
AnimatedVisibility
is also controlled by a boolean (therefore is always true within the conditional that shows the
Popup
). I even tried setting a timer on the
AnimatedVisibility
enable toggle so it would explicitly occur after the first if statement, but that still does not do the fade properly
Copy code
var animateVisibility by remember { mutableStateOf(false) }
    val coroutineScope = rememberCoroutineScope()
    coroutineScope.launch {
        delay(500)
        animateVisibility = true
    }
    Box(modifier) {
        parentComposable()
        if (showTooltip) {
            Popup(popupPositionProvider = popupPositionProvider) {
                AnimatedVisibility(
                    visible = animateVisibility,
                    enter = fadeIn(
                        // Fade in with the initial alpha of 0.3f.
                        initialAlpha = 0f,
                        animationSpec = TweenSpec(durationMillis = 2000)
                    )
                ) {
                    tooltipContent()
                }
            }
        }
    }
this is the animated within the conditional I would expect to work but does not
a

Albert Chang

01/31/2023, 1:28 AM
You can use
Copy code
AnimatedVisibility(
    visibleState = remember { MutableTransitionState(false).apply { targetState = true } }
)
8 Views