[SOLVED] How to show Drop down Menu where ever I touch in a box Jetpack Compose in android studio


This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under
CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

Issue

I want to show my DropdownMenu where ever I touch but it doesn’t work. I used offset to set the location of my drop down menu but it doesn’t work properly. It looks like it only sets the x value to the location of my drop down menu.

            var expanded by remember { mutableStateOf(false) }
            var touchPoint: Offset by remember { mutableStateOf(Offset.Zero) }
            val density = LocalDensity.current

            Box(
                Modifier
                    .fillMaxSize()
                    .background(Color.Cyan)
                    .pointerInput(Unit) {
                        detectTapGestures {
                            Log.d(TAG, "onCreate: ${it}")
                            touchPoint = it
                            expanded = true

                        }

                    }
            ) {
                val (xDp, yDp) = with(density) {
                    (touchPoint.x.toDp()) to (touchPoint.y.toDp())
                }
                DropdownMenu(
                    modifier = Modifier.align(Alignment.Center),
                    expanded = expanded,
                    offset = DpOffset(xDp, yDp),
                    onDismissRequest = {
                        expanded = false
                    },

                    ) {
                    DropdownMenuItem(onClick = {
                        expanded = false

                    }) {
                        Text("Copy")
                    }
                    DropdownMenuItem(onClick = { expanded = false }) {
                        Text("Get Balance")
                    }
                }

            }

screenshot

Solution

What you actually should be doing is offseting upward by giving a negative Offset.

You need get height of your parent you can get it via Modifier.onSizeChanged or using BoxWithConstraints if it covers whole parent.

I used BoxWithConstraints for demonstration but both can be used.

If you offset by maxHeight or height of the Composable Dropdown menu appears at the top so we need another positive offset which is y axis of touch position to move it down

@Composable
private fun DropDownSample() {
    var expanded by remember { mutableStateOf(false) }
    var touchPoint: Offset by remember { mutableStateOf(Offset.Zero) }
    val density = LocalDensity.current

    BoxWithConstraints(
        Modifier
            .fillMaxSize()
            .background(Color.Cyan)
            .pointerInput(Unit) {
                detectTapGestures {
                    Log.d("TAG", "onCreate: ${it}")
                    touchPoint = it
                    expanded = true

                }

            }
    ) {
        val (xDp, yDp) = with(density) {
            (touchPoint.x.toDp()) to (touchPoint.y.toDp())
        }
        DropdownMenu(
            expanded = expanded,
            offset = DpOffset(xDp, -maxHeight + yDp),
            onDismissRequest = {
                expanded = false
            }
        ) {

            DropdownMenuItem(
                onClick = {
                    expanded = false
                },
                interactionSource = MutableInteractionSource(),
                text = {
                    Text("Copy")
                }
            )

            DropdownMenuItem(
                onClick = {
                    expanded = false
                },
                interactionSource = MutableInteractionSource(),
                text = {
                    Text("Get Balance")
                }
            )
        }
    }
}

As can be seen in gif if you touch area where Dropdown appears if you touch the bottom of the screen it is moved up to top of the Composable. It’s at the end of the gif. I don’t know what’s causing this. Other than this issue it works as expected.

enter image description here

Answered By – Thracian

people found this article helpful. What about you?