Bei der Arbeit mit Google Workspace for Education mit Touch-Ereignissen und Animationen, im Vergleich zur Animationen zu erstellen. Zunächst müssen wir möglicherweise eine laufende Animation unterbrechen, wenn Touch-Ereignisse beginnen, da eine Nutzerinteraktion die höchste Priorität haben sollte.
Im folgenden Beispiel verwenden wir ein Animatable
, um den Versatz der Position
Kreiskomponente. Touch-Ereignisse werden mit dem
pointerInput
Modifikator. Wird ein neues Tippereignis erkannt, wird animateTo
aufgerufen, um die
Versatzwert auf die Tippposition setzen. Während der Animation kann ein Tippereignis stattfinden.
In diesem Fall unterbricht animateTo
die laufende Animation und startet
die Animation an die neue Zielposition an, während die Geschwindigkeit der
unterbrochene Animation.
@Composable fun Gesture() { val offset = remember { Animatable(Offset(0f, 0f), Offset.VectorConverter) } Box( modifier = Modifier .fillMaxSize() .pointerInput(Unit) { coroutineScope { while (true) { // Detect a tap event and obtain its position. awaitPointerEventScope { val position = awaitFirstDown().position launch { // Animate to the tap position. offset.animateTo(position) } } } } } ) { Circle(modifier = Modifier.offset { offset.value.toIntOffset() }) } } private fun Offset.toIntOffset() = IntOffset(x.roundToInt(), y.roundToInt())
Ein weiteres häufiges Muster ist die Synchronisierung
von Animationswerten mit Werten.
von Touch-Ereignissen wie Drag. Im Beispiel unten sehen wir
Schließen" als Modifier
implementiert werden (anstatt das Tag
SwipeToDismiss
zusammensetzbar). Der horizontale Versatz des Elements wird als
Animatable
Diese API hat eine Eigenschaft, die für die Bewegungsanimation nützlich ist. Das
kann durch Touch-Ereignisse und die Animation geändert werden. Wenn wir eine
Touchdown-Ereignis: Animatable
stoppen wir mit der stop
-Methode, sodass alle
wird die laufende Animation
abgefangen.
Während eines Drag-Ereignisses verwenden wir snapTo
, um den Animatable
-Wert mit dem
Wert, der aus Touch-Ereignissen berechnet wurde. Mit der E-Mail-Funktion „Schreiben“
VelocityTracker
, um Drag-Ereignisse aufzuzeichnen und die Geschwindigkeit zu berechnen. Die Geschwindigkeit kann
für die Fling-Animation direkt in animateDecay
eingespeist werden. Wenn wir eine Position
um den Offset-Wert auf die ursprüngliche Position zurückzuversetzen, geben wir den Ziel-Offset an.
0f
-Wert mit der animateTo
-Methode.
fun Modifier.swipeToDismiss( onDismissed: () -> Unit ): Modifier = composed { val offsetX = remember { Animatable(0f) } pointerInput(Unit) { // Used to calculate fling decay. val decay = splineBasedDecay<Float>(this) // Use suspend functions for touch events and the Animatable. coroutineScope { while (true) { val velocityTracker = VelocityTracker() // Stop any ongoing animation. offsetX.stop() awaitPointerEventScope { // Detect a touch down event. val pointerId = awaitFirstDown().id horizontalDrag(pointerId) { change -> // Update the animation value with touch events. launch { offsetX.snapTo( offsetX.value + change.positionChange().x ) } velocityTracker.addPosition( change.uptimeMillis, change.position ) } } // No longer receiving touch events. Prepare the animation. val velocity = velocityTracker.calculateVelocity().x val targetOffsetX = decay.calculateTargetValue( offsetX.value, velocity ) // The animation stops when it reaches the bounds. offsetX.updateBounds( lowerBound = -size.width.toFloat(), upperBound = size.width.toFloat() ) launch { if (targetOffsetX.absoluteValue <= size.width) { // Not enough velocity; Slide back. offsetX.animateTo( targetValue = 0f, initialVelocity = velocity ) } else { // The element was swiped away. offsetX.animateDecay(velocity, decay) onDismissed() } } } } } .offset { IntOffset(offsetX.value.roundToInt(), 0) } }
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Wertbezogene Animationen
- Ziehen, wischen und werfen
- Touch-Gesten