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

KamilH

11/06/2020, 2:18 PM
Is it possible to position UI element in relation to root? I’m gathering element position with `onGloballyPositioned`’s
positionInRoot
after that I would like to show another composable which would be full screen (would have the same size as root) and then position some composable in a position I gathered before. Is something like that possible? Maybe there is a method that will let me put (or try to put if it’s in bounds)
placable
position relative to root?
a

Adam Powell

11/06/2020, 2:27 PM
Do you have a visual mock or example of the effect you're trying to create? From the description it sounds like you're trying to create a pop-up menu of some sort anchored to another element?
c

caelum19

11/06/2020, 2:45 PM
I have made something for highlighting individual components in a way like that, I feel like there has got to be a better way to do it though so interested on comments
Copy code
class TutorialContainerScope() {
    var selectedX: Float by mutableStateOf(0f)
    var selectedY: Float by mutableStateOf(0f)
    var selectedHeight: Int by mutableStateOf(0)
    var selectedWidth: Int by mutableStateOf(0)

    var anyVisible by mutableStateOf(false)
    var overlayContent: @Composable () -> Unit = { }

    @Composable
    fun Modifier.updatePos(visible: Boolean) = this.then(onGloballyPositioned {
        if (visible) {
            selectedX = it.positionInRoot.x
            selectedY = it.positionInRoot.y
            selectedWidth = it.size.width
            selectedHeight = it.size.height
        }
    })

    @Composable()
    fun coachElement(modifier: Modifier, showCoach: Boolean, content: @Composable () -> Unit) {
        if (showCoach) {
            anyVisible = true
            overlayContent = content
        }
        // Draw normally, even if showCoach == true, to obtain the position
        Box(modifier.updatePos(showCoach), Alignment.TopCenter) {
            content()
        }
    }
}

@OptIn(ExperimentalAnimationApi::class)
@Composable
fun TutorialContainer(
    modifier: Modifier = Modifier.fillMaxSize(),
    overallContent: @Composable() (TutorialContainerScope.() -> Unit),
    color: Color = Color(0x0000009A),
) {
    val tutorialContainerScope = TutorialContainerScope()
    ConstraintLayout(Modifier.fillMaxSize()) {
        overallContent(tutorialContainerScope)
        if (tutorialContainerScope.anyVisible) androidx.compose.foundation.layout.Box(
            Modifier
                .fillMaxSize()
                .background(Color.Black.copy(alpha = 0.5f))
                .zIndex(2f)
        )
        val contentConstraint = createRef()
        with(DensityAmbient.current) {
            Box(Modifier.zIndex(3f).constrainAs(contentConstraint) {
                val selectedX = tutorialContainerScope.selectedX
                start.linkTo(parent.start, selectedX.toDp())
                val selectedY = tutorialContainerScope.selectedY
                top.linkTo(<http://parent.top|parent.top>, selectedY.toDp())
                width = Dimension.value(tutorialContainerScope.selectedWidth.toDp())
                height = Dimension.value(tutorialContainerScope.selectedHeight.toDp())
            }, alignment = Alignment.TopStart) {
                tutorialContainerScope.overlayContent()
            }
        }
    }
}


@Preview()
@Composable()
fun usage() {
    TutorialContainer(overallContent = {
        Row(modifier = Modifier.size(300.dp, 700.dp), horizontalArrangement = Arrangement.SpaceBetween) {
            coachElement(Modifier.size(120.dp, 120.dp), false) {
                androidx.compose.foundation.layout.Box(Modifier.background(Color.Green).size(20.dp))
            }
            coachElement(Modifier.align(Alignment.Bottom).fillMaxSize(0.3f), true) {
                androidx.compose.foundation.layout.Box((Modifier.background(Color.Blue).fillMaxSize()))
            }
        }
    }, color = Color.Green)
}
k

KamilH

11/06/2020, 2:45 PM
I would like to recreate this animation in Compose. In Android view’s world I implemented it with fullscreen dialog which is showing icon that is animating from right top corner to center of the screen and I would like to try the same approach in Compose 🙂 But popup menu anchored to another element is also a good example of this, actually I it was second thing in my mind to implement
2 Views