Gebaren en springanimaties
Natuurlijke, op fysica gebaseerde beweging.
Gebaren en springanimaties is een gratis Android Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Android Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Android Academy bevat in totaal 4 lessen.
Interactieve, fysieke beweging
De aantrekkelijkste animaties reageren op de vinger van de gebruiker en voelen aan als echte objecten, met vaart en veerkracht. Om deze te bouwen combineer je gebaren met animaties op basis van natuurkundige principes.
In deze les behandel je Animatable, veren, afnemende snelheid na een veegbeweging en het koppelen hiervan aan sleepgebaren voor een natuurlijke, interactieve gebruikersinterface.
Animatable: besturing op laag niveau
Waar animate*AsState op status reageert, geeft Animatable je imperatieve besturing. Je bewaart een exemplaar ervan in remember en bestuurt het vanuit een coroutine met aanroepen zoals animateTo of snapTo.
Dit vormt de basis voor beweging die door gebaren wordt aangestuurd.
@Composable
fun BounceOnClick() {
val scale = remember { Animatable(1f) }
val scope = rememberCoroutineScope()
Box(
Modifier
.graphicsLayer { scaleX = scale.value; scaleY = scale.value }
.clickable {
scope.launch {
scale.animateTo(1.3f, spring())
scale.animateTo(1f, spring())
}
}
)
}Veren: dampingRatio en stiffness
Een spring-configuratie wordt bepaald door twee waarden:
- dampingRatio - hoe veerkrachtig. Een lagere waarde stuitert meer;
1f(kritisch gedempt) schiet niet door. - stiffness - hoe snel. Een hogere waarde bereikt het doel sneller.
Compose biedt constanten zoals Spring.DampingRatioMediumBouncy en Spring.StiffnessLow, zodat je zelden onbewerkte getallen nodig hebt.
val spec = spring<Float>(
dampingRatio = Spring.DampingRatioLowBouncy,
stiffness = Spring.StiffnessMedium
)
// later, inside a coroutine:
// offset.animateTo(targetValue = 0f, animationSpec = spec)Sleepbewegingen detecteren
Om beweging interactief te maken, lees je aanraakinvoer uit. Modifier.pointerInput met detectDragGestures rapporteert verplaatsingen tijdens het slepen terwijl de gebruiker zijn vinger beweegt.
Je telt die verplaatsingen op in een verschuiving en past die toe op de composable.
@Composable
fun Draggable() {
var offsetX by remember { mutableStateOf(0f) }
Box(
Modifier
.offset { IntOffset(offsetX.roundToInt(), 0) }
.size(80.dp)
.background(Color.Red)
.pointerInput(Unit) {
detectDragGestures { change, drag ->
change.consume()
offsetX += drag.x
}
}
)
}Met een veer terugveren
Combineer slepen met Animatable voor een effect waarbij het element terugveert. Tijdens het slepen gebruik je snapTo om de vingerpositie direct over te nemen; na het loslaten gebruik je animateTo(0f) met een veer, zodat het element terug naar zijn beginpositie stuitert.
@Composable
fun SnapBack() {
val offsetX = remember { Animatable(0f) }
val scope = rememberCoroutineScope()
Box(
Modifier
.offset { IntOffset(offsetX.value.roundToInt(), 0) }
.size(80.dp)
.background(Color.Blue)
.pointerInput(Unit) {
detectDragGestures(
onDrag = { change, drag ->
change.consume()
scope.launch { offsetX.snapTo(offsetX.value + drag.x) }
},
onDragEnd = {
scope.launch { offsetX.animateTo(0f, spring()) }
}
)
}
)
}Slingeren met snelheid
Bij een echte veegbeweging blijft het element bewegen nadat de vinger is opgetild. Houd de snelheid bij met een VelocityTracker en geef die vervolgens door aan animateDecay, zodat het element op natuurlijke wijze uitrolt en stopt met behulp van een wrijvingsgebaseerde DecayAnimationSpec.
val decay = rememberSplineBasedDecay<Float>()
// on drag end, with measured velocity:
// scope.launch {
// offsetX.animateDecay(
// initialVelocity = velocity,
// animationSpec = decay
// )
// }Vegen om te sluiten met ankers
Voor veegbewegingen met vaste rustposities, zoals vegen om te sluiten, springt anchoredDraggable naar gedefinieerde ankers. Je declareert de toestanden en hun posities in pixels, waarna Compose de veerbeweging ertussen afhandelt.
enum class DragValue { Start, End }
val state = remember {
AnchoredDraggableState(
initialValue = DragValue.Start,
anchors = DraggableAnchors {
DragValue.Start at 0f
DragValue.End at 300f
}
)
}Oneindige en herhalende animaties
Gebruik voor continue beweging, zoals een pulserende stip of een glans-effect tijdens het laden, rememberInfiniteTransition met infiniteRepeatable. Stel RepeatMode in op Reverse voor een heen-en-weerbeweging, of op Restart om telkens opnieuw te beginnen.
@Composable
fun Pulse() {
val transition = rememberInfiniteTransition(label = "pulse")
val scale by transition.animateFloat(
initialValue = 1f,
targetValue = 1.2f,
animationSpec = infiniteRepeatable(
animation = tween(700),
repeatMode = RepeatMode.Reverse
),
label = "scale"
)
Box(Modifier.graphicsLayer { scaleX = scale; scaleY = scale })
}Beweging en veer combineren
Het kenmerkende interactieve patroon: slepen om te bewegen en loslaten om tot rust te komen. Houd tijdens het slepen de snelheid bij en laat het element daarna met animateDecay doorschieten of naar een ankerpunt bewegen met een spring, afhankelijk van de afstand of snelheid.
Zo voelen onderste panelen, carrousels en kaarten die je kunt sluiten precies zo natuurlijk aan.
// pattern:
// 1) onDrag -> animatable.snapTo(current + delta)
// 2) onDragEnd -> if (fast) animatable.animateDecay(velocity, decay)
// else animatable.animateTo(nearestAnchor, spring())Tot rust komen met een veer in puur Kotlin
Om te ervaren hoe een veer tot rust komt, bekijken we hier een minimale lus in puur Kotlin. Bij elke stap past de lus een herstellende kracht richting het doel toe en dempt hij de snelheid. Compose gebruikt per frame hetzelfde idee.
fun main() {
var pos = 0f
var vel = 0f
val target = 200f
val stiffness = 0.2f
val damping = 0.75f
repeat(8) { step ->
vel = (vel + (target - pos) * stiffness) * damping
pos += vel
println("step $step pos=${"%.1f".format(pos)}")
}
}Tikken, indrukken en meerdere bewegingen
Slepen is niet de enige beweging. pointerInput biedt ook detectTapGestures voor tikken, dubbeltikken en lang indrukken, en detectTransformGestures voor knijpen om in en uit te zoomen en voor roteren.
Hier activeert lang indrukken een veeranimatie voor de schaal, waarbij bewegingsdetectie wordt gecombineerd met een Animatable.
@Composable
fun LongPressScale() {
val scale = remember { Animatable(1f) }
val scope = rememberCoroutineScope()
Box(
Modifier
.graphicsLayer { scaleX = scale.value; scaleY = scale.value }
.pointerInput(Unit) {
detectTapGestures(
onLongPress = {
scope.launch { scale.animateTo(1.4f, spring()) }
},
onPress = {
tryAwaitRelease()
scope.launch { scale.animateTo(1f, spring()) }
}
)
}
)
}Korte controle
Je bouwt een kaart die je kunt verslepen en die na het loslaten moet terugveren naar de oorspronkelijke positie. Welke combinatie past bij de gebruikelijke aanpak in Compose?
Samenvatting: bewegingen en veren
Je kunt nu natuurlijke, interactieve beweging bouwen:
Animatablebiedt imperatieve besturing vanuit coroutines viaanimateToensnapTo.springwordt afgestemd metdampingRatio(stuiteren) enstiffness(snelheid).pointerInputendetectDragGestureszetten aanraking om in beweging;animateDecayvoegt doorschieten toe.anchoredDraggablespringt voor veeginteracties naar vaste posities.rememberInfiniteTransitionstuurt herhalende effecten aan, zoals pulseren en glans-effecten.
Daarmee is Animations in Jetpack Compose afgerond. Je kunt nu vol vertrouwen waarden, zichtbaarheid, inhoud en bewegingen animeren.
Leer Kotlin met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 36
- Lessen
- 152
Veelgestelde vragen
Is de les “Gebaren en springanimaties” gratis?
Ja — je kunt hier op het web alle 3 lessen van het leerpad Android Academy, waaronder “Gebaren en springanimaties”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Android Academy bevat in totaal 4 lessen.
Wat leer ik in “Gebaren en springanimaties”?
Natuurlijke, op fysica gebaseerde beweging. Je oefent met Android Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Android Academy te beginnen?
Ervaring vooraf is niet nodig. Android Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.
Hoe lang duurt de les “Gebaren en springanimaties”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Android Academy?
Ja. Elke les over Android Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Waarom animaties belangrijk zijn
- De basis van animate*AsState
- AnimatedVisibility en transities
- Gebaren en springanimaties