Se7eN
02/12/2021, 2:45 PMpointerInput
modifier to allow dragging inside my Box
. The problem is when the locked
parameter (and other parameters) change, onPositionChange
and onDragStateChange
still executes with the old value of the parameters. Like if locked
was true by default and the state changes to false, the if statement in onPositionChange
will still run. I don't know it might be related to some kotlin magic but I was using the now deprecated dragGestureFilter
modifier before alpha12 and it was working fine with the same code. I've also tried using detectDragGestures
inside pointerInput
but no luck.fun Parent() {
val locked by remember { mutableStateOf(true) }
MyComposable(locked, ...)
}
fun MyComposable(locked: Boolean, ...) {
val inputModifier = Modifier.simpleDragInput(
onDragStateChange = { dragging -> ... },
onPositionChange = { dragPosition ->
if(locked) {
...
}
}
)
Box(modifier = inputModifier)
}
fun Modifier.simpleDragInput(
onPositionChange: (Offset) -> Unit,
onDragStateChange: (Boolean) -> Unit,
): Modifier = pointerInput(Unit) {
forEachGesture {
awaitPointerEventScope {
val down = awaitFirstDown()
onDragStateChange(true)
onPositionChange(down.position)
drag(down.id) { change ->
change.consumePositionChange(
change.position.x - change.previousPosition.x,
change.position.y - change.previousPosition.y
)
onPositionChange(change.position)
}
onDragStateChange(false)
}
}
}
Vsevolod Ganin
02/12/2021, 2:51 PMpointerInput(Unit)
is remembering your first passed lambda for composition lifetime. Your should pass appropriate keys to make it update lambdaonPositionChange
and onDragStateChange
and they remember first seen locked
valueSe7eN
02/12/2021, 2:53 PMVsevolod Ganin
02/12/2021, 2:54 PMSe7eN
02/12/2021, 2:54 PMVsevolod Ganin
02/12/2021, 2:56 PMDisposableEffect
and LaunchedEffect
. Moreover this behavior is due to the fact that pointerInput
relies on LaunchedEffect
in its implementationSe7eN
02/12/2021, 3:10 PMVsevolod Ganin
02/12/2021, 3:15 PMremember
in the first place, so they were always new on every recomposition. So try to inspect each key if it is different on every recompositionmanueldidonna
02/12/2021, 3:18 PMSe7eN
02/12/2021, 3:29 PMrememberUpdatedState
. I do have a list key that is updated inside onPositionChanged
using the drag position. I'll try making a minimal reproducible exampleAdam Powell
02/12/2021, 3:58 PMpointerInput
determine when your detector state machine will reset, and rememberUpdatedState
lets you update things like these callbacks out from under the running pointerInput
state machine without resetting it. The pattern @manueldidonna is describing above is:
fun Modifier.simpleGesture(
onGesture: () -> Unit
): Modifier {
val currentOnGesture by rememberUpdatedState(onGesture)
// Unit because we do not want to restart
return pointerInput(Unit) {
// ...
// when detected, call currentOnGesture, not onGesture.
// currentOnGesture is kept up to date by composition.
currentOnGesture()
}
}
Se7eN
02/12/2021, 4:02 PMAdam Powell
02/12/2021, 4:06 PMSe7eN
02/12/2021, 4:08 PM