Customize the click animation on Compose UI
First, create a state to trigger the animation from start to end.
there using the function pointerInput to detect the gestures:
Modifier .pointerInput(key1 = this) { // block
awaitPointerEventScope {
while (true) {
buttonState = if (buttonState == ButtonState.Pressed) {
waitForUpOrCancellation(PointerEventPass.Initial)
ButtonState.Idle
} else {
awaitFirstDown(true)
ButtonState.Pressed
}
}
}
}
- key1 is a value that involves the `block` that should be re-executed when its content changes. (and the previous `block` will be canceled.)
- when we set the `this` keyword as key1 variable, we suppose to know this `block` executed once only.
- inside the `awaitPointerEventScope`, we should run a while loop always to prevent leaving this code.
- awaitFirstDown is a suspend function waiting for the action down event from the user.
and... if A and B are buttons like below:
and... if A and B are buttons like below:
- requireUnconsumed set to
- the annotation is we can't write this code above a `clickable` function, the event will be consumed by that `clickable` function.`true` will let you receive the event touched on A except on B.
`false` will let you receive the event both touched on the A and B.
🆇 DON'T
🆅 DO
Modifier
.pointerInput(this) { /* ... */ }
.clickable { /* ... */ }
🆅 DO
Modifier
.clickable { /* ... */ }
.pointerInput(this) { /* ... */ }
Animate the values
Now, we can create the Transition object from this button state. or use animaxxToState APIs to create custom animations.
var buttonState by remember { mutableStateOf(ButtonState.Idle) }
val transition = updateTransition(targetState = buttonState, label = "buttonState")
a shadow animation will look like this:
val animatedElevation by transition.animateDp(
targetValueByState = { if (it == ButtonState.Pressed) 0.dp else elevationSize },
label = ""
)
use animatedElevation to shadow function
Modifier .shadow(
animatedElevation,
CardDefaults.shape,
ambientColor = MaterialTheme.colorScheme.surface,
spotColor = ShadowGray
)
Wrapper this function as an extension of the Modifier
fun Modifier.animateBouncePress(elevationSize: Dp) = composed(
inspectorInfo = debugInspectorInfo {
name = "animateBouncePress"
properties["elevationSize"] = elevationSize
}) { /* the implement */ }
留言
張貼留言