Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to position a custom Popup using other components' positions

I have a custom Popup:

        if (expanded) {
            Popup(
                onDismissRequest = {},
                properties = PopupProperties(
                    clippingEnabled = false
                ),
                popupPositionProvider = object : PopupPositionProvider {
                    override fun calculatePosition(
                        anchorBounds: IntRect,
                        windowSize: IntSize,
                        layoutDirection: LayoutDirection,
                        popupContentSize: IntSize
                    ): IntOffset {
                        return IntOffset(
                            x = textXPosition,
                            y = barYPosition
                        )
                    }
                }
            ) {
                Text(
                    text = "This is the popup content.",
                    modifier = Modifier.background(Color.White)
                )
            }
        }

where textXPosition and barYPosition are determined at follows:


textXPosition:

        var textXPosition by remember { mutableStateOf(0) }

        Text(
            text = state.currentFileName,
            modifier = Modifier
                .weight(1f)
                .padding(start = 8.dp)
                .clickable { expanded = !expanded }
                .onGloballyPositioned { coordinates ->
                    textXPosition = coordinates.positionInRoot().x.toInt()
                }
        )

        if (expanded) {...}

barYPosition:

    var barYPosition by remember {
        mutableStateOf(0)
    }

    ActionBar(
        modifier = Modifier
            .height(36.dp)
            .background(Color(0xfffafafa))
            .onGloballyPositioned { coordinates ->
                barYPosition = coordinates.positionInRoot().y.toInt()
            }
    ...)


What I get in the end is on the picture:

enter image description here

The idea was that the popup would be directly above the text, but there's actually a small gap and I have no idea why..

like image 213
Sebastian Lore Avatar asked Oct 20 '25 00:10

Sebastian Lore


1 Answers

If you anchor PopUp and your content inside a Box and set offset by height of PopUp to up it should work as expected.

@Preview
@Composable
private fun Test() {

    var barYPosition by remember {
        mutableStateOf(0)
    }

    Column(
        modifier = Modifier.fillMaxSize().background(Color.Black)
    ) {

        TopAppBar(
            modifier = Modifier
                .height(36.dp)
                .background(Color(0xfffafafa))
        ) {

        }
        Spacer(modifier = Modifier.weight(1f))


        Box(
            modifier = Modifier.border(2.dp, Color.Red)
        ) {

            Popup(
                onDismissRequest = {},
                offset = IntOffset(0, y = -barYPosition),
                properties = PopupProperties(
                    clippingEnabled = false
                )
            ) {
                Text(
                    text = "This is the popup content.",
                    modifier = Modifier.background(Color.White)
                        .onPlaced {
                            barYPosition = it.size.height
                        }
                )
            }
            Row(
                modifier = Modifier.fillMaxWidth().background(Color.White),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text(
                    "Some Text Needed",
                    fontSize = 24.sp
                )
                Spacer(modifier = Modifier.weight(1f))

                Icon(imageVector = Icons.Default.Settings, contentDescription = null)
            }
        }
    }
}
like image 86
Thracian Avatar answered Oct 22 '25 13:10

Thracian