Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Prevent dragging box out of the screen with Jetpack Compose

I have such code from here: https://developer.android.com/jetpack/compose/gestures

    Box(modifier = Modifier.fillMaxSize()) {
        var offsetX by remember { mutableStateOf(0f) }
        var offsetY by remember { mutableStateOf(0f) }

        Box(
            Modifier
                .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
                .background(Color.Red)
                .size(120.dp) // makes it rectangle. wrap_content without it
                .align(Alignment.BottomEnd)
                .pointerInput(Unit) {
                    detectDragGestures { change, dragAmount ->
                        change.consume()
                        offsetX += dragAmount.x
                        offsetY += dragAmount.y
                    }
                }

        ) {
            // todo
        }
    }

So for end side of x I create something like this:

val newOffsetX = if ((offsetX + dragAmount.x) < 0) { offsetX + dragAmount.x } else { 0 }
offsetX = newOffsetX

But how can I found start of x and prevent my draggable box go out of screen?
Is there a way to do it for both X and Y?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

If you align your draggable box with Alignment.TopStart you can coerce min and max width and height between 0 and parent size – box size

@Composable
private fun DragSample() {

    BoxWithConstraints(modifier = Modifier.fillMaxSize()) {
        var offsetX by remember { mutableStateOf(0f) }
        var offsetY by remember { mutableStateOf(0f) }

        val parentWidth = constraints.maxWidth
        val parentHeight = constraints.maxHeight
        Box(
            Modifier
                .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
                .background(Color.Red)
                .size(120.dp) // makes it rectangle. wrap_content without it
                .align(Alignment.TopStart)
                .pointerInput(Unit) {

                    val boxSize = this.size
                    detectDragGestures { _, dragAmount ->
                        offsetX = (offsetX + dragAmount.x).coerceIn(
                            0f,
                            parentWidth - boxSize.width.toFloat()
                        )
                        offsetY = (offsetY + dragAmount.y).coerceIn(
                            0f,
                            parentHeight - boxSize.height.toFloat()
                        )
                    }
                }

        ) {
            // todo
        }
    }
}

If you wish to start from Alignemnt.BottomEnd you should do it as

@Composable
private fun DragSample() {

    BoxWithConstraints(modifier = Modifier.fillMaxSize()) {
        var offsetX by remember { mutableStateOf(0f) }
        var offsetY by remember { mutableStateOf(0f) }

        val parentWidth = constraints.maxWidth
        val parentHeight = constraints.maxHeight
        Box(
            Modifier
                .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
                .background(Color.Red)
                .size(120.dp) // makes it rectangle. wrap_content without it
                .align(Alignment.BottomEnd)
                .pointerInput(Unit) {

                    val boxSize = this.size
                    detectDragGestures { _, dragAmount ->
                        offsetX = (offsetX + dragAmount.x).coerceIn(
                             boxSize.width.toFloat() -parentWidth,
                            0f
                        )
                        offsetY = (offsetY + dragAmount.y).coerceIn(
                             boxSize.height.toFloat() -parentHeight,
                            0f
                        )
                    }
                }

        ) {
            // todo
        }
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading