When using `rememberDraggableState` and vibrating ...
# compose
z
When using
rememberDraggableState
and vibrating after a certain drag distance, I often see the vibration not staying in sync with the drag events. Is this a bug? Code in thread 🧵
Copy code
inline fun Modifier.draggable(
    minimumOffset: Dp = 30.dp,
    crossinline onDragged: (DragDirection) -> Unit
): Modifier {
    return composed {
        val vibrator = rememberVibrator()

        var offset = remember { 0f }

        val minimumOffsetPx = with(LocalDensity.current) {
            minimumOffset.toPx()
        }

        draggable(
            orientation = Vertical,
            onDragStopped = {
                offset = 0f
            },
            state = rememberDraggableState { delta ->
                offset += delta

                if (offset.absoluteValue >= minimumOffsetPx) {
                    offset = 0f

                    val direction = when {
                        delta <= 0 -> Up
                        else -> Down
                    }

                    onDragged(direction)

                    vibrator.vibrate(Light)
                }
            }
        )
    }
}

enum class DragDirection {

    Up,
    Down;
}
vibrator.vibrate() leads to this
Copy code
val effect = VibrationEffect.createOneShot(
    vibration.length(),
    DEFAULT_AMPLITUDE
)

vibrator.vibrate(effect)
a
You should use
var offset by remember { mutableStateOf(0f) }
.
z
@Albert Chang I had that previously, but the behavior was identical. I dont think its needed here though, Im just doing calculations based on it and I dont need any "state" effects?
a
It may coincidentally work but it's wrong.
remember
in your code is pointless and
offset
will be reset to 0 on every recomposition. You don't necessarily need a mutable state but you definitely need a value holder.
z
Thanks, Ill switch to
mutableStateOf
👍🏽 The pure logic of the
Modifier
works flawlessly, e.g. the drag
Up/Down
is invoked accordingly, but the vibration effect is not.