This message was deleted.
# compose
s
This message was deleted.
m
My guess is that the local variables of the lambda passed to
detectDragGestures
are already fixed when first called, so position is always
IntOffset.Zero
. Explicitly using the
value
parameter of the state solves this:
Copy code
@Composable
fun DraggableSample() {
    Box(
        modifier = Modifier
            .fillMaxSize()
    ) {
        val position = remember { mutableStateOf(IntOffset.Zero) }

        DraggableCircle(position = position, onPositionChanged = { position.value = it })
    }
}

@Composable
fun DraggableCircle(
    modifier: Modifier = Modifier,
    position: MutableState<IntOffset>,
    onPositionChanged: (position: IntOffset) -> Unit
) {
    Box(
        modifier = modifier
            .offset { position.value }
            .size(100.dp)
            .background(color = Color.Green, CircleShape)
            .pointerInput(Unit) {
                detectDragGestures { change, dragAmount ->
                    onPositionChanged(dragAmount.toIntOffset() + position.value)
                    change.consumeAllChanges()
                }
            }
    )
}

private fun Offset.toIntOffset() = IntOffset(x.roundToInt(), y.roundToInt())
I don't know if there's a more elegant solution to this, but this works.
a
You have two choices, one is to change the
position
parameter to
positionChange
and add the change on the call site (
onPositionChange = { position += it }
), the other is to add
var currentPosition by rememberUpdatedState(position)
in
DraggableCircle
and use
currentPosition
in
pointerInput
. Passing
MutableState
as parameter is not a good idea I'm afraid.
👍 1