'Why can't I use `AnimatedVisibility` in a `BoxScope`?

I have a layout which looks like this:

Row {
        ...

        Box(
            modifier = Modifier
                .fillMaxHeight()
                .width(50.dp)
        ) {
            AnimatedVisibility(
                visible = isSelected && selectedAnimationFinished,
                enter = fadeIn(),
                exit = fadeOut()
            ) {
                ...
            }
        }
    }

But I get the compile-time error:

fun RowScope.AnimatedVisibility(visible: Boolean, modifier: Modifier = ..., enter: EnterTransition = ..., exit: ExitTransition = ..., content: AnimatedVisibilityScope.() -> Unit): Unit' can't be called in this context by implicit receiver. Use the explicit one if necessary

It appears that Kotlin finds the AnimatedVisibility function ambiguous, since Compose exposes multiple AnimatedVisibility functions with the same signature: there's a fun AnimatedVisibility with no receiver, and a fun RowScope.AnimatedVisibility which requires RowScope.

From what I can gather, Kotlin is complaining about me using the RowScope version incorrectly, but I just want to use the version with no receiver!

Using this.AnimatedVisibility also doesn't help.

The only workaround I've found that works is to fully qualify the name, like androidx.compose.animation.AnimatedVisibility(...). But I have no idea why this works.

Can anyone shed some light on this? Is there a better option I can use than fully qualifying the name?



Solution 1:[1]

Looks like it's a bug in the language - overload resolution is not aware of @DslMarkers and such stuff. I couldn't find related issues on Kotlin bugtracker so I filed one myself - https://youtrack.jetbrains.com/issue/KT-48215.

Solution 2:[2]

One workaround is to use a fully qualified name:

Box {
    androidx.compose.animation.AnimatedVisibility(visibile = ...) {
        ...
    }
}

Solution 3:[3]

I had this problem too, I used StateValue for the value of the AnimatedVisibility with a default value of true. I found out that was fixed to me by giving the StateValue a default value of false and then using LaunchedEffect to change the value to true, or by clicking on any view on the screen that changes the value to true.

Solution 4:[4]

Another workaround is creating new composable method and using it in a Row:

@Composable
fun AnimatedThings() {
    Box {
        AnimatedVisiblity(visible = ...) {
            ...
        }
     }
 }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jeffset
Solution 2 Alex Perevozchykov
Solution 3 T HC
Solution 4 Cemal