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

Mehdi Haghgoo

05/17/2022, 4:27 AM
Why cannot we change the x,y coordinates of composables with modifiers?
c

Chris Sinco [G]

05/17/2022, 4:33 AM
You can with the offset modifier
m

Mehdi Haghgoo

05/17/2022, 4:46 AM
Please see this. The touch location and the object being dragged are different. I think this is a problem.
k

Kirill Grouchnikov

05/17/2022, 4:47 AM
There's no code here, so you are asking to diagnose the problem in the dark
👍🏻 1
m

Mehdi Haghgoo

05/17/2022, 4:48 AM
Here I am updating an offset state and using it with the offset() modifier. But, besides the first time I drag the object away from the original location, the pointer location is different from the offset.
@Kirill Grouchnikov I'm sorry. Here's the code:
Copy code
var offsetX by remember{mutableStateOf(0f)}
    var offsetY by remember{mutableStateOf(0f)}
    Canvas(
            Modifier
                .pointerInput(Unit){
                    detectDragGestures{change,dragAmount->
                        offsetX += dragAmount.x
                        offsetY += dragAmount.y
                    }
                }
                .offset{IntOffset(x=offsetX.roundToInt(), y = offsetY.roundToInt())}
                .padding(8.dp)
                .size(100.dp)
                .border(1.dp, Color.Blue)
                .background(Color.Cyan)
                .drawBehind {
                    drawCircle(Color.Red, size.minDimension/3)
                }



        ){
c

Chris Sinco [G]

05/17/2022, 5:06 AM
Looks like the offset modifier needs to be first, before the pointerInput modifier
❤️ 1
m

Mehdi Haghgoo

05/17/2022, 5:17 AM
Yes it solved the problem. Can I have an explanation why this happens? I know orders matter, but here it's a bit tricky to explain.
c

Chris Sinco [G]

05/17/2022, 5:23 AM
In this case, the offset needs to be applied first because everything after is the UI element you want to move. You can paste this snippet into Studio and play around with the order of offset and pointerInput to see the different outcomes:
Copy code
@Preview
@Composable
fun DragTest() {
    MaterialTheme {
        var offsetX by remember{ mutableStateOf(0f) }
        var offsetY by remember{ mutableStateOf(0f) }

        Surface {
            Box(Modifier.fillMaxSize()) {
                Canvas(
                    Modifier
                        .size(60.dp)
                        .border(4.dp, Color.Green)
                        .pointerInput(Unit) {
                            detectDragGestures{ change, dragAmount->
                                offsetX += dragAmount.x
                                offsetY += dragAmount.y
                            }
                        }
                        .offset { IntOffset(x = offsetX.roundToInt(), y = offsetY.roundToInt()) }
                        .padding(8.dp)
                        .size(100.dp)
                        .border(1.dp, Color.Blue)
                        .background(Color.Cyan)
                        .drawBehind {
                            drawCircle(Color.Red, size.minDimension/3)
                        }
                ) {}
            }
        }
    }
}
With that snippet above, dragging is only applied when dragging from the green square.
5 Views