Das Eigenschaftsanimationssystem ist ein robustes Framework, mit dem Sie fast alles zu animieren. Sie können eine Animation definieren, um Objekteigenschaften im Laufe der Zeit zu ändern, unabhängig davon, ob sie auf dem Bildschirm erscheint oder nicht. Eine Eigenschaftsanimation ändert die (ein Feld in einem Objekt) über einen bestimmten Zeitraum hinweg. Um etwas zu animieren, müssen Sie Objekteigenschaft, die animiert werden soll, etwa die Position eines Objekts auf dem Bildschirm, die Dauer und zwischen den Werten, zwischen denen die Animation erfolgen soll.
Mit dem Eigenschaftsanimationssystem können Sie die folgenden Eigenschaften eines Animation:
- Dauer: Sie können die Dauer einer Animation festlegen. Die Standardlänge beträgt 300 ms.
- Zeitinterpolation: Sie können angeben, wie die Werte für die Eigenschaft berechnet werden, der aktuell verstrichenen Zeit der Animation.
- Wiederholungsanzahl und -verhalten: Sie können angeben, ob eine Animation wiederholt werden soll, wenn das Ende einer Dauer erreicht und wie oft die Animation wiederholt werden soll. Sie können auch geben Sie an, ob die Animation rückwärts wiedergegeben werden soll. Umgekehrte Wiedergaben festlegen wird die Animation wiederholt vor- und zurückgespult, bis die gewünschte Anzahl an Wiederholungen erreicht ist.
- Animationssets: Animationen können in logischen Gruppen zusammengefasst werden, die zusammen oder oder nach bestimmten Verzögerungen.
- Verzögerung bei Frame-Aktualisierung: Sie können angeben, wie oft die Frames der Animation aktualisiert werden sollen. Die ist standardmäßig so eingestellt, dass eine Aktualisierung alle 10 ms erfolgt. Die Geschwindigkeit, mit der Ihre Anwendung Frames aktualisieren kann, ist jedoch hängt letztendlich davon ab, wie voll das System insgesamt ist und wie schnell es den zugrunde liegenden Timer bedienen kann.
Ein vollständiges Beispiel für eine Immobilienanimation finden Sie in der
Klasse ChangeColor
in CustomTransition
auf GitHub.
Funktionsweise von Property-Animationen
Sehen wir uns zunächst anhand eines einfachen Beispiels an, wie eine Animation funktioniert. Abbildung 1 zeigt eine
hypothetisches Objekt, das mit seiner x
-Eigenschaft animiert ist, die seine
horizontalen Position auf einem Bildschirm. Die Dauer der Animation ist auf 40 ms und die Entfernung
40 Pixel beträgt. Alle 10 ms (Standard-Frame-Aktualisierungsrate) wird das Objekt verschoben.
horizontal x 10 Pixel. Nach 40 ms stoppt die Animation und das Objekt endet bei
horizontale Position 40. Dies ist ein Beispiel für eine Animation mit linearer Interpolation, d. h.
sich mit konstanter Geschwindigkeit bewegt.
Sie können Animationen auch so definieren, dass sie eine nicht lineare Interpolation haben. Abbildung 2 zeigt eine hypothetisches Objekt, das zu Beginn der Animation beschleunigt und am Ende der Animation. Das Objekt bewegt sich in 40 ms immer noch um 40 Pixel, aber nicht linear. Im am Anfang, wird diese Animation bis zur Hälfte beschleunigt und dann bis zum Ende der Animation. Wie Abbildung 2 zeigt, ist die zurückgelegte Strecke am Anfang und am Ende der Animation ist kleiner als in der Mitte.
Sehen wir uns genauer an, wie die wichtigen Komponenten des Animationen wie die oben dargestellten berechnet. Abbildung 3 zeigt, wie die Hauptklassen miteinander arbeiten.
Das ValueAnimator
-Objekt verfolgt das Timing Ihrer Animation.
z. B. wie lange die Animation läuft, und der aktuelle Wert der Eigenschaft,
zu animieren.
ValueAnimator
kapselt ein TimeInterpolator
, das die Animationsinterpolation definiert, und ein TypeEvaluator
, das definiert, wie die Werte für die zu berechnende Eigenschaft berechnet werden.
animiert. In Abbildung 2 wird beispielsweise TimeInterpolator
verwendet:
AccelerateDecelerateInterpolator
und TypeEvaluator
wäre IntEvaluator
.
Um eine Animation zu starten, erstellen Sie ein ValueAnimator
mit dem
für die Property, die Sie animieren möchten, sowie die Start- und Endwerte
der Animation. Wenn Sie start()
aufrufen, wird die Animation
beginnt. Während der gesamten Animation berechnet ValueAnimator
einen verstrichenen Bruch.
zwischen 0 und 1, je nach Dauer der Animation und verstrichener Zeit. Die
Verstrichene Bruchzahl stellt die Zeit in Prozent dar, die die Animation abgeschlossen ist. 0 bedeutet 0 %.
und 1 für 100%. In Abbildung 1 wäre beispielsweise der verstrichene Bruch bei t = 10 ms 0,25
da die Gesamtdauer t = 40 ms beträgt.
Wenn ValueAnimator
mit der Berechnung eines verstrichenen Bruchs fertig ist,
ruft den aktuell festgelegten TimeInterpolator
auf, um einen
interpolierter Bruch Ein interpolierter Teil ordnet den verstrichenen Teil einem neuen
Bruch, der die festgelegte Zeitinterpolation berücksichtigt. In Abbildung 2 ist beispielsweise
da die Animation langsam beschleunigt wird, ist der interpolierte Bruch von etwa 0,15 kleiner als der Wert
verstrichener Bruchteil, 0,25, bei t = 10 ms. In Abbildung 1 ist der interpolierte Bruch immer gleich
der verstrichene Teil.
Wenn der interpolierte Bruch berechnet wird, ruft ValueAnimator
auf
das entsprechende TypeEvaluator
, um den Wert des
basierend auf dem interpolierten Bruch, dem Startwert und der Eigenschaft
Endwert der Animation. In Abbildung 2 lag der interpolierte Bruch beispielsweise bei 0,15 bei t =
10 ms, sodass der Wert für die Eigenschaft zu diesem Zeitpunkt 0,15 × (40 - 0) oder 6 wäre.
Unterschied zwischen Eigenschaftsanimation und Ansichtsanimation
Das Ansichtsanimationssystem bietet die Möglichkeit, nur View
zu animieren.
Objekte. Wenn Sie also Nicht-View
-Objekte animieren möchten, müssen Sie
eigenen Code erstellen. Das Ansichtsanimationssystem ist außerdem dadurch eingeschränkt, dass es nur
einige Aspekte eines View
-Objekts zum Animieren bereithält, z. B. die Skalierung und
beispielsweise die Rotation einer Ansicht, aber nicht die Hintergrundfarbe.
Ein weiterer Nachteil des Ansichtsanimationssystems besteht darin, dass es nur dort geändert wurde, wo das Die Ansicht wurde gezeichnet, nicht die eigentliche Ansicht. Wenn Sie beispielsweise eine Schaltfläche zum Verschieben über den Bildschirm ziehen, wird die Schaltfläche korrekt gezeichnet, aber an der tatsächlichen Position, an der Sie auf das Symbol ändert sich nichts, Sie müssen also Ihre eigene Logik dafür implementieren.
Mit dem Eigenschaftsanimationssystem werden diese Einschränkungen vollständig entfernt, und Sie können Jede Eigenschaft eines beliebigen Objekts (Views und Nicht-Views) und das Objekt selbst wird tatsächlich geändert. Das Eigenschaftsanimationssystem ist außerdem robuster in der Art und Weise, wie es Animationen durchführt. Bei weisen Sie den zu animierenden Eigenschaften wie Farbe, Position oder Größe und können Aspekte der Animation definieren, z. B. Interpolation und für die Synchronisierung mehrerer Animatoren.
Das Ansichtsanimationssystem nimmt jedoch weniger Zeit für die Einrichtung in Anspruch und erfordert weniger Code zum Schreiben. Wenn die Ansichtsanimation alles erledigt hat, was Sie tun müssen, oder wenn Ihr vorhandener Code bereits wie gewünscht funktioniert, ist das Eigenschaftsanimationssystem nicht erforderlich. Es könnte auch ist es sinnvoll, beide Animationssysteme für verschiedene Situationen zu verwenden.
API-Übersicht
Die meisten APIs des Property-Animationssystems finden Sie in android.animation
. Da das Ansichtsanimationssystem
viele Interpolatoren in android.view.animation
definiert, können Sie
Interpolatoren im Eigenschaftsanimationssystem. In den folgenden Tabellen werden die wichtigsten
des Eigenschaftsanimationssystems.
Die Klasse Animator
bietet die Grundstruktur für das Erstellen
Animationen. Normalerweise verwenden Sie diese Klasse nicht direkt, da sie nur minimale
Funktionen, die erweitert werden müssen, um Animationswerte vollständig zu unterstützen. Die folgenden
abgeleiteten Klassen erweitern Animator
:
Klasse | Beschreibung |
---|---|
ValueAnimator |
Das Haupt-Timing-Modul für die Eigenschaftsanimation, das auch die Werte für die
zu animieren. Sie verfügt über alle Hauptfunktionen zum Berechnen von Animationen
und enthält die Timing-Details jeder Animation, Informationen darüber, ob ein
Animationswiederholungen, Listener, die Update-Ereignisse empfangen, und die Möglichkeit, benutzerdefinierte
die auszuwerten sind. Animationseigenschaften bestehen aus zwei Teilen:
und legen Sie diese Werte für das Objekt und die Eigenschaft fest, die animiert werden. Das zweite Stück wird in ValueAnimator nicht ausgeführt, du musst also zuhören
für Aktualisierungen von Werten, die von ValueAnimator berechnet wurden und
modifizieren Sie die Objekte, die Sie mit Ihrer eigenen Logik animieren möchten. Weitere Informationen finden Sie im Abschnitt zu
Weitere Informationen zu Animationen mit ValueAnimator |
ObjectAnimator |
Eine abgeleitete Klasse von ValueAnimator , mit der Sie ein Ziel festlegen können
Objekt und Objekteigenschaft, die animiert werden sollen. Diese Klasse aktualisiert das Attribut entsprechend, wenn
wird ein neuer Wert für die Animation berechnet. Sie möchten
in den meisten Fällen ObjectAnimator ,
da dies die Animation von Werten
in Zielobjekten vereinfacht. Sie können jedoch
Sie möchten ValueAnimator direkt verwenden, da für ObjectAnimator weitere Einschränkungen gelten, z. B. dass bestimmte
Zugriffsmethoden, die auf dem Zielobjekt vorhanden sein müssen. |
AnimatorSet |
Bietet einen Mechanismus zum Gruppieren von Animationen, sodass sie in in Beziehung zueinander stehen. Sie können Animationen so festlegen, dass sie zusammen, hintereinander oder danach wiedergegeben werden einer bestimmten Verzögerung. Weitere Informationen finden Sie im Abschnitt Choreografen mehrerer für Animationen mit Animator-Sets. |
Evaluatoren teilen dem Animationssystem von Eigenschaften mit, wie die Werte für eine bestimmte
Property. Sie verwenden die Zeitdaten, die von einem Animator
-Klasse, den Start- und Endwert der Animation und berechnet die animierten Werte der Eigenschaft
basierend auf diesen Daten. Im Animationssystem für Unterkünfte stehen die folgenden Bewerter zur Verfügung:
Klasse/Schnittstelle | Beschreibung |
---|---|
IntEvaluator |
Der Standard-Evaluator zur Berechnung von Werten für int -Properties. |
FloatEvaluator |
Der Standard-Evaluator zur Berechnung von Werten für float -Properties. |
ArgbEvaluator |
Der Standard-Evaluator zur Berechnung von Werten für dargestellte Farbeigenschaften als Hexadezimalwerte. |
TypeEvaluator |
Eine Schnittstelle, mit der Sie Ihren eigenen Evaluator erstellen können. Wenn Sie eine Animation für
Objekteigenschaft, die kein int , float oder Farbe ist,
müssen Sie die Schnittstelle TypeEvaluator implementieren, um anzugeben, wie
zur Berechnung der animierten Werte der Objekteigenschaft. Sie können auch einen benutzerdefinierten TypeEvaluator für int , float und Farbe angeben
verwenden, wenn Sie diese Typen anders als das Standardverhalten verarbeiten möchten.
Weitere Informationen finden Sie im Abschnitt TypeEvaluator verwenden.
Informationen zur Entwicklung eines benutzerdefinierten Evaluators. |
Ein Zeitinterpolator definiert, wie bestimmte Werte in einer Animation als
Zeitfunktion. Sie können z. B. festlegen, dass Animationen linear über den gesamten
Animation, d. h. die Animation bewegt sich gleichmäßig über die gesamte Zeit, Sie können aber auch Animationen
um nicht lineare Zeit zu verwenden, z. B. die Beschleunigung am Anfang und die Verzögerung am Anfang
Ende der Animation. In Tabelle 3 werden die Interpolatoren beschrieben, die in android.view.animation
enthalten sind. Wenn keiner der verfügbaren Interpolatoren geeignet ist
implementieren Sie die TimeInterpolator
-Schnittstelle und erstellen Sie Ihre eigene. Weitere Informationen zum Schreiben eines benutzerdefinierten Elements finden Sie unter Interpolatoren verwenden.
Interpolator.
Klasse/Schnittstelle | Beschreibung |
---|---|
AccelerateDecelerateInterpolator |
Interpolator, dessen Änderungsrate langsam beginnt und endet, aber beschleunigt wird durch die Mitte gehen. |
AccelerateInterpolator |
Interpolator, deren Änderungsrate langsam beginnt, beschleunigt. |
AnticipateInterpolator |
Interpolator, deren Änderung rückwärts beginnt und dann nach vorne gleitet. |
AnticipateOvershootInterpolator |
Interpolator, dessen Änderung rückwärts beginnt, vorwärts schwebt und überschreitet auf den Zielwert und kehrt schließlich zum Endwert zurück. |
BounceInterpolator |
Ein Interpolator, dessen Änderung am Ende zurückspringt. |
CycleInterpolator |
Interpolator, deren Animation für eine bestimmte Anzahl von Zyklen wiederholt wird. |
DecelerateInterpolator |
Interpolatoren, deren Änderungsrate schnell beginnt, langsamer wird. |
LinearInterpolator |
Ein Interpolator, dessen Änderungsrate konstant ist. |
OvershootInterpolator |
Interpolator, dessen Änderung nach vorne wirft und den letzten Wert überschreitet. zurück. |
TimeInterpolator |
Eine Schnittstelle, mit der Sie Ihren eigenen Interpolator implementieren können. |
Animationen mit ValueAnimator
Mit der Klasse ValueAnimator
können Sie Werte eines Typs für die
Dauer einer Animation durch Angabe eines Satzes von int
, float
oder einer Farbe
zu animierende Werte. Sie erhalten ein ValueAnimator
, indem Sie eine der
seine Factory-Methoden: ofInt()
, ofFloat()
oder ofObject()
. Beispiel:
Kotlin
ValueAnimator.ofFloat(0f, 100f).apply { duration = 1000 start() }
Java
ValueAnimator animation = ValueAnimator.ofFloat(0f, 100f); animation.setDuration(1000); animation.start();
In diesem Code beginnt ValueAnimator
mit der Berechnung der Werte der
Animation zwischen 0 und 100 für eine Dauer von 1.000 ms, wenn die Methode start()
ausgeführt wird.
Sie können auch einen benutzerdefinierten Typ für die Animation angeben. Gehen Sie dazu folgendermaßen vor:
Kotlin
ValueAnimator.ofObject(MyTypeEvaluator(), startPropertyValue, endPropertyValue).apply { duration = 1000 start() }
Java
ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue); animation.setDuration(1000); animation.start();
In diesem Code beginnt ValueAnimator
mit der Berechnung der Werte der
zwischen startPropertyValue
und endPropertyValue
unter Verwendung des
Logik, die von MyTypeEvaluator
für eine Dauer von 1.000 ms bereitgestellt wird, wenn die Methode start()
ausgeführt wird.
Sie können die Werte der Animation verwenden, indem Sie
AnimatorUpdateListener
an das ValueAnimator
-Objekt an, wie im
folgenden Code:
Kotlin
ValueAnimator.ofObject(...).apply { ... addUpdateListener { updatedAnimation -> // You can use the animated value in a property that uses the // same type as the animation. In this case, you can use the // float value in the translationX property. textView.translationX = updatedAnimation.animatedValue as Float } ... }
Java
animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator updatedAnimation) { // You can use the animated value in a property that uses the // same type as the animation. In this case, you can use the // float value in the translationX property. float animatedValue = (float)updatedAnimation.getAnimatedValue(); textView.setTranslationX(animatedValue); } });
Im onAnimationUpdate()
können Sie auf den aktualisierten Animationswert zugreifen und ihn in der Eigenschaft
eine Ihrer Ansichten. Weitere Informationen zu Listenern finden Sie im Abschnitt
Animations-Listener:
Mit ObjectAnimator animieren
ObjectAnimator
ist eine abgeleitete Klasse von ValueAnimator
(wie im vorherigen Abschnitt besprochen) und kombiniert die zeitliche Abfolge
Berechnung von ValueAnimator
mit der Möglichkeit,
Benannte Eigenschaft eines Zielobjekts animieren Das macht das Animieren von Objekten viel einfacher,
ValueAnimator.AnimatorUpdateListener
nicht mehr implementieren müssen,
da die animierte Eigenschaft automatisch aktualisiert wird.
Das Instanziieren eines ObjectAnimator
ähnelt einem ValueAnimator
, Sie geben jedoch zusätzlich das Objekt und den Namen der Eigenschaft dieses Objekts (als
einen String) zusammen mit den Werten, zwischen denen animiert werden soll:
Kotlin
ObjectAnimator.ofFloat(textView, "translationX", 100f).apply { duration = 1000 start() }
Java
ObjectAnimator animation = ObjectAnimator.ofFloat(textView, "translationX", 100f); animation.setDuration(1000); animation.start();
Damit die ObjectAnimator
-Attribute aktualisiert werden
müssen Sie Folgendes tun:
- Die Objekteigenschaft, die Sie animieren, muss eine Setter-Funktion (im Camel-Case-Schreibweise) in Form von
set<PropertyName>()
Da dieObjectAnimator
wird die Property während der Animation automatisch aktualisiert, muss aber Zugriff auf die Property haben. mit dieser Setter-Methode. Lautet der Name der Property beispielsweisefoo
, müssen Sie haben einesetFoo()
-Methode. Wenn diese Setter-Methode nicht existiert, gibt es drei Optionen: <ph type="x-smartling-placeholder">- </ph>
- Fügen Sie die Setter-Methode zur Klasse hinzu, wenn Sie über die entsprechenden Rechte verfügen.
- Verwenden Sie eine Wrapper-Klasse, zu deren Änderung Sie berechtigt sind, und legen Sie fest, dass dieser Wrapper die -Wert mit einer gültigen Setter-Methode an und leiten ihn an das ursprüngliche Objekt weiter.
- Verwende stattdessen
ValueAnimator
.
- Wenn Sie nur einen Wert für den Parameter
values...
in einer derObjectAnimator
-Factory-Methoden angeben, wird davon ausgegangen, dass es sich um den Endwert des Animation. Daher muss die Objekteigenschaft, die Sie animieren, eine Getter-Funktion haben. das den Startwert der Animation ermittelt. Die Getter-Funktion muss im Parameter Form vonget<PropertyName>()
. Lautet der Eigenschaftsname beispielsweisefoo
, du benötigst einegetFoo()
-Methode. - Die Getter- und Setter-Methoden der zu animierenden Eigenschaft müssen bei Bedarf
verwenden denselben Typ wie die Start- und Endwerte, die Sie für
ObjectAnimator
angeben. Zum Beispiel müssen SietargetObject.setPropName(float)
undtargetObject.getPropName()
wenn Sie die folgendeObjectAnimator
erstellen:ObjectAnimator.ofFloat(targetObject, "propName", 1f)
- Je nach Eigenschaft oder Objekt, die bzw. das Sie animieren, müssen Sie möglicherweise die Methode
invalidate()
für eine Ansicht aufrufen, damit der Bildschirm neu gezeichnet wird. aktualisierte animierte Werte. Sie tun dies in deronAnimationUpdate()
Callback des Nutzers an. Beispielsweise führt die Animation der Farbeigenschaft eines Drawable-Objekts nur zu Aktualisierungen der Eigenschaft wenn sich dieses Objekt von selbst neu zeichnet. Alle Property-Setter in der Datenansicht, z. B.setAlpha()
undsetTranslationX()
die View ordnungsgemäß entwerten. Sie müssen die View also nicht entwerten, wenn Sie diese aufrufen. mit neuen Werten. Weitere Informationen zu Listenern finden Sie im Abschnitt Animations-Listener:
Mit einem AnimatorSet mehrere Animationen choreografieren
Häufig möchten Sie eine Animation abspielen,
die davon abhängt, wann eine andere Animation beginnt
beendet. Im Android-System kannst du Animationen in einem AnimatorSet
bündeln, um anzugeben, ob sie gestartet werden sollen
sequenziell oder nach einer bestimmten Verzögerung. Sie können AnimatorSet
-Objekte auch ineinander verschachteln.
Mit dem folgenden Code-Snippet wird Folgendes wiedergegeben: Animator
-Objekte auf folgende Weise verwenden:
bounceAnim
wird abgespielt.squashAnim1
,squashAnim2
,stretchAnim1
undstretchAnim2
.bounceBackAnim
wird abgespielt.fadeAnim
wird abgespielt.
Kotlin
val bouncer = AnimatorSet().apply { play(bounceAnim).before(squashAnim1) play(squashAnim1).with(squashAnim2) play(squashAnim1).with(stretchAnim1) play(squashAnim1).with(stretchAnim2) play(bounceBackAnim).after(stretchAnim2) } val fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply { duration = 250 } AnimatorSet().apply { play(bouncer).before(fadeAnim) start() }
Java
AnimatorSet bouncer = new AnimatorSet(); bouncer.play(bounceAnim).before(squashAnim1); bouncer.play(squashAnim1).with(squashAnim2); bouncer.play(squashAnim1).with(stretchAnim1); bouncer.play(squashAnim1).with(stretchAnim2); bouncer.play(bounceBackAnim).after(stretchAnim2); ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f); fadeAnim.setDuration(250); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(bouncer).before(fadeAnim); animatorSet.start();
Animations-Listener
Mit den unten beschriebenen Listenern können Sie während der Dauer einer Animation auf wichtige Ereignisse warten.
Animator.AnimatorListener
onAnimationStart()
- Wird beim Start der Animation aufgerufen.onAnimationEnd()
– Wird aufgerufen, wenn die Animation endet.onAnimationRepeat()
: Wird aufgerufen, wenn sich die Animation wiederholt.onAnimationCancel()
: Wird beim Abbrechen der Animation aufgerufen. Eine abgebrochene Animation ruft auchonAnimationEnd()
an, unabhängig davon, wie sie beendet wurden.
ValueAnimator.AnimatorUpdateListener
-
onAnimationUpdate()
wird bei jedem Frame der Animation aufgerufen. Dieses Ereignis überwachen, um die vonValueAnimator
während eines Animation. Fragen Sie dasValueAnimator
-Objekt ab, um den Wert zu verwenden an das Ereignis übergeben werden, um den aktuellen animierten Wert mit der MethodegetAnimatedValue()
abzurufen. Die Implementierung dieser Listener ist erforderlich, wenn SieValueAnimator
verwenden.Je nachdem, welche Eigenschaft oder welches Objekt Sie animieren, müssen Sie möglicherweise
invalidate()
für eine Ansicht, um diesen Bereich der Ansicht zu erzwingen um sich mit den neuen animierten Werten neu zu zeichnen. Wenn Sie zum Beispiel die color-Eigenschaft eines Drawable-Objekts führt nur dann zu Aktualisierungen des Bildschirms, zeichnet sich neu. Alle Property-Setter in View, z. B.setAlpha()
undsetTranslationX()
macht die Ansicht ungültig Die Ansicht muss also nicht ungültig werden, wenn diese Methoden mit neuen Werten aufgerufen werden.
-
Sie können die Klasse AnimatorListenerAdapter
erweitern statt
Implementieren der Animator.AnimatorListener
-Schnittstelle, wenn Sie
alle Methoden des Animator.AnimatorListener
implementieren möchten,
. Die Klasse AnimatorListenerAdapter
liefert leere
Implementierungen der Methoden,
die überschrieben werden können.
Mit dem folgenden Code-Snippet wird beispielsweise ein AnimatorListenerAdapter
erstellt.
nur für onAnimationEnd()
Callback:
Kotlin
ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply { duration = 250 addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { balls.remove((animation as ObjectAnimator).target) } }) }
Java
ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f); fadeAnim.setDuration(250); fadeAnim.addListener(new AnimatorListenerAdapter() { public void onAnimationEnd(Animator animation) { balls.remove(((ObjectAnimator)animation).getTarget()); }
Layoutänderungen an ViewGroup-Objekten animieren
Das Eigenschaftsanimationssystem bietet die Möglichkeit, Änderungen an ViewGroup-Objekten zu animieren. und eine einfache Möglichkeit bieten, View-Objekte selbst zu animieren.
Sie können Layoutänderungen innerhalb einer ViewGroup animieren. Dazu verwenden Sie die
Klasse LayoutTransition
. Ansichten in einer ViewGroup können
durchlaufen beim Hinzufügen zu oder
aus einer ViewGroup entfernen oder die
Methode setVisibility()
mit
VISIBLE
, INVISIBLE
oder
GONE
. Die verbleibenden Datenansichten in der ViewGroup können auch
wenn Sie Ansichten hinzufügen oder entfernen. Sie können
die folgenden Animationen in einem LayoutTransition
-Objekt
durch Aufrufen von setAnimator()
und übergeben ein Animator
-Objekt mit einem der
folgende LayoutTransition
-Konstanten:
APPEARING
: Diese Markierung gibt die Animation an, die für Elemente ausgeführt wird, die im Container angezeigt werden.CHANGE_APPEARING
: Diese Markierung gibt die Animation an, die für Elemente ausgeführt wird, ändert sich, weil ein neues Element im Container erscheint.DISAPPEARING
: Diese Markierung gibt die Animation an, die für Elemente ausgeführt wird, wenn sie aus dem Container verschwinden.CHANGE_DISAPPEARING
: ein Flag, das die Animation angibt, die für Elemente ausgeführt wird, die die sich ändern, weil ein Element aus dem Container verschwindet.
Sie können Ihre eigenen benutzerdefinierten Animationen für diese vier Ereignistypen definieren, um das Aussehen anzupassen. Ihrer Layoutübergänge oder weisen Sie das Animationssystem einfach an, die Standardanimationen zu verwenden.
Um das Attribut android:animateLayoutchanges
auf true
für die
ViewGroup führt folgende Schritte aus:
<LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="match_parent" android:id="@+id/verticalContainer" android:animateLayoutChanges="true" />
Wenn Sie dieses Attribut auf „true“ setzen, werden Ansichten, die zur ViewGroup sowie die anderen Ansichten in der ViewGroup aus.
Änderungen des Ansichtsstatus mit StateListAnimator animieren
Mit der Klasse StateListAnimator
können Sie Animatoren definieren, die ausgeführt werden, wenn
ändert sich der Status einer Ansicht. Dieses Objekt verhält sich wie ein Wrapper für ein
Animator
-Objekt zu erstellen, das diese Animation aufruft, sobald die angegebene
Änderungen am Anzeigestatus (z. B. „gedrückt“ oder „fokussiert“).
Das StateListAnimator
kann in einer XML-Ressource mit einem Stamm definiert werden
<selector>
-Element und untergeordnete <item>
-Elemente, die jeweils
einen anderen Ansichtsstatus, der durch die Klasse StateListAnimator
definiert wird. Jedes
<item>
enthält die Definition für einen Eigenschaftsanimationssatz.
Mit der folgenden Datei wird beispielsweise ein Animationsfilm für die Statusliste erstellt, der die x- und y-Skalierung ändert. der Ansicht, wenn darauf gedrückt wird:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- the pressed state; increase x and y size to 150% --> <item android:state_pressed="true"> <set> <objectAnimator android:propertyName="scaleX" android:duration="@android:integer/config_shortAnimTime" android:valueTo="1.5" android:valueType="floatType"/> <objectAnimator android:propertyName="scaleY" android:duration="@android:integer/config_shortAnimTime" android:valueTo="1.5" android:valueType="floatType"/> </set> </item> <!-- the default, non-pressed state; set x and y size to 100% --> <item android:state_pressed="false"> <set> <objectAnimator android:propertyName="scaleX" android:duration="@android:integer/config_shortAnimTime" android:valueTo="1" android:valueType="floatType"/> <objectAnimator android:propertyName="scaleY" android:duration="@android:integer/config_shortAnimTime" android:valueTo="1" android:valueType="floatType"/> </set> </item> </selector>
Fügen Sie zum Anhängen des Animators der Statusliste an eine Ansicht den Parameter
android:stateListAnimator
so:
<Button android:stateListAnimator="@xml/animate_scale" ... />
Nun werden die in animate_scale.xml
definierten Animationen verwendet, wenn die
Statusänderungen.
Wenn Sie stattdessen einer Ansicht in Ihrem Code einen Animator für Statuslisten zuweisen möchten, verwenden Sie die Methode
AnimatorInflater.loadStateListAnimator()
-Methode und weisen Sie den Animationskünstler der
Ansicht mit der View.setStateListAnimator()
-Methode aufrufen.
Statt die Eigenschaften der Ansicht zu animieren, können Sie auch eine Drawable-Animation zwischen
Statusänderungen mithilfe von AnimatedStateListDrawable
.
Einige der System-Widgets in
In Android 5.0 werden diese Animationen standardmäßig verwendet. Das folgende Beispiel zeigt,
, um eine AnimatedStateListDrawable
als XML-Ressource zu definieren:
<!-- res/drawable/myanimstatedrawable.xml --> <animated-selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- provide a different drawable for each state--> <item android:id="@+id/pressed" android:drawable="@drawable/drawableP" android:state_pressed="true"/> <item android:id="@+id/focused" android:drawable="@drawable/drawableF" android:state_focused="true"/> <item android:id="@id/default" android:drawable="@drawable/drawableD"/> <!-- specify a transition --> <transition android:fromId="@+id/default" android:toId="@+id/pressed"> <animation-list> <item android:duration="15" android:drawable="@drawable/dt1"/> <item android:duration="15" android:drawable="@drawable/dt2"/> ... </animation-list> </transition> ... </animated-selector>
TypeEvaluator verwenden
Wenn Sie einen Typ animieren möchten, der dem Android-System nicht bekannt ist, können Sie Ihren eigenen
Evaluator durch Implementieren der TypeEvaluator
-Schnittstelle. Die Typen, die
dem Android-System bekannt sind, int
, float
oder eine Farbe, die
unterstützt vom Typ IntEvaluator
, FloatEvaluator
und ArgbEvaluator
Evaluierende.
Es gibt nur eine Methode, die im TypeEvaluator
implementiert werden kann.
die Methode evaluate()
. Dadurch können Sie
Animation, mit der Sie einen geeigneten Wert für Ihre animierte Eigenschaft im
den aktuellen Punkt der Animation. Die Klasse FloatEvaluator
zeigt,
Vorgehensweise:
Kotlin
private class FloatEvaluator : TypeEvaluator<Any> { override fun evaluate(fraction: Float, startValue: Any, endValue: Any): Any { return (startValue as Number).toFloat().let { startFloat -> startFloat + fraction * ((endValue as Number).toFloat() - startFloat) } } }
Java
public class FloatEvaluator implements TypeEvaluator { public Object evaluate(float fraction, Object startValue, Object endValue) { float startFloat = ((Number) startValue).floatValue(); return startFloat + fraction * (((Number) endValue).floatValue() - startFloat); } }
Hinweis: Wenn ValueAnimator
(oder ObjectAnimator
) ausgeführt wird, wird ein aktuell verstrichener Bruchteil des
Animation (ein Wert zwischen 0 und 1) und berechnet dann je nach
welchen Interpolator Sie verwenden. Der interpolierte Bruch ist das, was TypeEvaluator
über den Parameter fraction
empfängt. Sie müssen also
bei der Berechnung animierter Werte
den Interpolator nicht berücksichtigen müssen.
Interpolatoren verwenden
Ein Interpolator definiert, wie bestimmte Werte in einer Animation als Funktion von . Sie können z. B. festlegen, dass Animationen linear über die gesamte Animation laufen, Das heißt, die Animation wird gleichmäßig über die gesamte Zeit verschoben. Sie können aber auch Animationen festlegen, nicht linearen Zeitangaben verwendet, z. B. durch Beschleunigung oder Verzögerung am Anfang oder Ende des Animation.
Interpolatoren im Animationssystem erhalten einen Bruchteil von Animatoren, der die
verstrichene Zeit der Animation. Interpolatoren ändern diesen Bruch, sodass er mit dem Typ
Animation, die es liefern soll. Das Android-System bietet eine Reihe
gemeinsamer Interpolatoren
android.view.animation package
. Wenn keine der genannten
können Sie die TimeInterpolator
-Schnittstelle implementieren und Ihr
gehören.
Im Folgenden wird zum Beispiel verglichen, wie der Standardinterpolator AccelerateDecelerateInterpolator
und der LinearInterpolator
interpolierte Brüche berechnen.
LinearInterpolator
hat keine Auswirkungen auf den verstrichenen Bruch. AccelerateDecelerateInterpolator
beschleunigt die Animation und
schneller wieder aus dem Netzwerk raus. Die folgenden Methoden definieren die Logik für diese Interpolatoren:
AccelerateDecelerateInterpolator
Kotlin
override fun getInterpolation(input: Float): Float = (Math.cos((input + 1) * Math.PI) / 2.0f).toFloat() + 0.5f
Java
@Override public float getInterpolation(float input) { return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; }
LinearInterpolator
Kotlin
override fun getInterpolation(input: Float): Float = input
Java
@Override public float getInterpolation(float input) { return input; }
In der folgenden Tabelle sind die Näherungswerte aufgeführt, die mithilfe dieser Interpolatoren für eine Animation, die 1.000 ms dauert:
ms verstrichen | Verstrichener/interpolierter Bruch (linear) | Interpolierter Bruch (beschleunigen/verlangsamen) |
---|---|---|
0 | 0 | 0 |
200 | ,2 | 0,1 |
400 | 0,4 | 0,345 |
600 | 0,6 | 0,8 |
800 | 0,8 | 0,9 |
1000 | 1 | 1 |
Wie die Tabelle zeigt, ändert LinearInterpolator
die Werte
mit derselben Geschwindigkeit, also 0,2 pro 200 ms. AccelerateDecelerateInterpolator
ändert die Werte schneller als LinearInterpolator
zwischen 200 ms und 600 ms und langsamer zwischen 600 ms und
1.000 ms.
Keyframes festlegen
Ein Keyframe
-Objekt besteht aus einem Zeit/Wert-Paar, mit dem Sie
zu einem bestimmten Zeitpunkt
einer Animation einen bestimmten Zustand erreicht. Jeder Keyframe kann auch einen eigenen
Interpolator ein, um das Verhalten der Animation im Intervall zwischen den vorherigen
der Keyframe-Zeit und die Zeit dieses Keyframes.
Zum Instanziieren eines Keyframe
-Objekts müssen Sie eine der Factory-
ofInt()
, ofFloat()
oder ofObject()
, um den entsprechenden Keyframe
-Typ zu erhalten. Anschließend rufen Sie
ofKeyframe()
-Factory-Methode verwenden,
PropertyValuesHolder
-Objekt abrufen Sobald Sie das Objekt haben, können Sie
einen Animationskünstler abrufen, indem Sie das PropertyValuesHolder
-Objekt übergeben und
das zu animierende Objekt. Das folgende Code-Snippet zeigt, wie dies funktioniert:
Kotlin
val kf0 = Keyframe.ofFloat(0f, 0f) val kf1 = Keyframe.ofFloat(.5f, 360f) val kf2 = Keyframe.ofFloat(1f, 0f) val pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2) ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation).apply { duration = 5000 }
Java
Keyframe kf0 = Keyframe.ofFloat(0f, 0f); Keyframe kf1 = Keyframe.ofFloat(.5f, 360f); Keyframe kf2 = Keyframe.ofFloat(1f, 0f); PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2); ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation); rotationAnim.setDuration(5000);
Ansichten animieren
Das Eigenschaftsanimationssystem ermöglicht eine optimierte Animation von View-Objekten und -Angeboten. gegenüber dem Ansichtsanimationssystem. Ansicht Animationssystem transformierte View-Objekte, indem sie die Art und Weise änderte, wie sie gezeichnet wurden. Dies war im Container jeder View verarbeitet werden, da die View selbst keine Eigenschaften hatte, die geändert werden konnten. Dies führte dazu, dass die View animiert wurde, jedoch keine Änderung im View-Objekt selbst. Dieses führte zum Verhalten eines Objekts, das noch an seinem ursprünglichen Ort existierte, obwohl es an einer anderen Stelle auf dem Bildschirm gezeichnet werden. In Android 3.0 werden neue Eigenschaften und die entsprechenden Getter- und Setter-Methoden hinzugefügt, um diesen Nachteil zu eliminieren.
Das Eigenschaftsanimationssystem
können Ansichten auf dem Bildschirm animieren, indem Sie die tatsächlichen Eigenschaften in den View-Objekten ändern. In
Darüber hinaus wird in Views automatisch auch die invalidate()
, um den Bildschirm zu aktualisieren, wenn seine Eigenschaften geändert werden. Die neuen Properties in der View
-Klasse, die Eigenschaftsanimationen vereinfachen, sind:
translationX
undtranslationY
: Mit diesen Eigenschaften wird gesteuert, wo Die Ansicht befindet sich als Delta von ihren linken und oberen Koordinaten, die durch ihr Layout festgelegt werden. Container.rotation
,rotationX
undrotationY
: Diese Properties Sie können die Drehung in 2D (Eigenschaftrotation
) und 3D um den Drehpunkt steuern.scaleX
undscaleY
: Diese Eigenschaften steuern die 2D-Skalierung eines Ansicht um seinen Drehpunkt herum.pivotX
undpivotY
: Mit diesen Eigenschaften wird der Speicherort der Drehpunkt, um den die Transformationen für Drehung und Skalierung stattfinden. Standardmäßig weist der Pivot befindet sich in der Mitte des Objekts.x
undy
: Dies sind einfache Dienstprogrammeigenschaften zur Beschreibung des Die endgültige Position der Ansicht in ihrem Container als Summe der Werte "left" und "top" TranslationX- und TranslationY-Werte.alpha
: Stellt die Alphatransparenz in der Ansicht dar. Dieser Wert ist 1 (opak) Der Wert 0 steht für vollständige Transparenz (nicht sichtbar).
Zum Animieren einer Eigenschaft eines View-Objekts, etwa der Farbe oder des Rotationswerts, müssen Sie nur erstellen Sie einen Eigenschaftsanimationer und geben die View-Eigenschaft an, die Sie zu animieren. Beispiel:
Kotlin
ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f)
Java
ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);
Weitere Informationen zum Erstellen von Animatoren finden Sie in den Abschnitten zum ValueAnimator und ObjectAnimator:
Mit ViewPropertyAnimator animieren
Mit ViewPropertyAnimator
lassen sich ganz einfach mehrere
Attribute einer View
parallel, unter Verwendung einer einzelnen zugrunde liegenden Animator
-Objekt enthält. Es verhält sich ähnlich wie ein ObjectAnimator
, weil es den Parameter
tatsächlichen Werte der Ansichtseigenschaften. Sie ist jedoch effizienter, wenn viele Eigenschaften
einmal. Außerdem ist der Code zur Verwendung von ViewPropertyAnimator
viel
prägnanter und leichter zu lesen sind. Die folgenden Code-Snippets zeigen die Unterschiede bei der Verwendung mehrerer
ObjectAnimator
Objekte, ein einzelnes
ObjectAnimator
und die ViewPropertyAnimator
, wenn
Dabei werden die Eigenschaften x
und y
einer Ansicht gleichzeitig animiert.
Mehrere ObjectAnimator-Objekte
Kotlin
val animX = ObjectAnimator.ofFloat(myView, "x", 50f) val animY = ObjectAnimator.ofFloat(myView, "y", 100f) AnimatorSet().apply { playTogether(animX, animY) start() }
Java
ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f); ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f); AnimatorSet animSetXY = new AnimatorSet(); animSetXY.playTogether(animX, animY); animSetXY.start();
One ObjectAnimator
Kotlin
val pvhX = PropertyValuesHolder.ofFloat("x", 50f) val pvhY = PropertyValuesHolder.ofFloat("y", 100f) ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start()
Java
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f); ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start();
ViewPropertyAnimator
Kotlin
myView.animate().x(50f).y(100f)
Java
myView.animate().x(50f).y(100f);
Genauere Informationen zu ViewPropertyAnimator
findest du auf den entsprechenden Android-Entwicklern.
Blog
veröffentlichen.
Animationen in XML deklarieren
Mit dem Eigenschaftsanimationssystem können Sie Eigenschaftsanimationen mit XML deklarieren, die Sie programmatisch nutzen können. Wenn Sie Ihre Animationen in XML definieren, können Sie sie ganz einfach wiederverwenden. in mehreren Aktivitäten verknüpfen und die Animationssequenz einfacher bearbeiten können.
Um Animationsdateien zu unterscheiden, in denen die neuen APIs für Eigenschaftenanimationen verwendet werden, von denen, in denen die
Legacy-Framework Animation ansehen,
Ab Android 3.1 sollten Sie die XML-Dateien für Eigenschaftsanimationen im Verzeichnis res/animator/
speichern.
Für die folgenden Eigenschaftsanimationsklassen wird die XML-Deklaration mit dem folgenden XML-Tags:
ValueAnimator
–<animator>
ObjectAnimator
–<objectAnimator>
AnimatorSet
–<set>
Die Attribute, die Sie in Ihrer XML-Deklaration verwenden können, finden Sie unter Animation Ressourcen Im folgenden Beispiel werden die beiden Gruppen von Objektanimationen wiedergegeben. nacheinander, wobei der erste verschachtelte Satz zwei Objektanimationen zusammen abspielt:
<set android:ordering="sequentially"> <set> <objectAnimator android:propertyName="x" android:duration="500" android:valueTo="400" android:valueType="intType"/> <objectAnimator android:propertyName="y" android:duration="500" android:valueTo="300" android:valueType="intType"/> </set> <objectAnimator android:propertyName="alpha" android:duration="500" android:valueTo="1f"/> </set>
Zum Ausführen dieser Animation müssen Sie die XML-Ressourcen in Ihrem Code in ein AnimatorSet
-Objekt aufblähen und dann die Zielobjekte für alle Animationen festlegen.
bevor der Animationssatz gestartet wird. Durch den Aufruf von setTarget()
wird der Einfachheit halber ein einzelnes Zielobjekt für alle untergeordneten Elemente von AnimatorSet
festgelegt. Der folgende Code zeigt, wie dies funktioniert:
Kotlin
(AnimatorInflater.loadAnimator(myContext, R.animator.property_animator) as AnimatorSet).apply { setTarget(myObject) start() }
Java
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.animator.property_animator); set.setTarget(myObject); set.start();
Sie können ValueAnimator
auch in XML deklarieren, wie
Beispiel:
<animator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:valueType="floatType" android:valueFrom="0f" android:valueTo="-100f" />
Um die vorherige ValueAnimator
in Ihrem Code zu verwenden, müssen Sie
das Objekt aufblähen muss, ein
AnimatorUpdateListener
,
den aktualisierten Animationswert abrufen
und in einer Property Ihrer Datenansichten verwenden,
Dies wird im folgenden Code dargestellt:
Kotlin
(AnimatorInflater.loadAnimator(this, R.animator.animator) as ValueAnimator).apply { addUpdateListener { updatedAnimation -> textView.translationX = updatedAnimation.animatedValue as Float } start() }
Java
ValueAnimator xmlAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.animator); xmlAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator updatedAnimation) { float animatedValue = (float)updatedAnimation.getAnimatedValue(); textView.setTranslationX(animatedValue); } }); xmlAnimator.start();
Informationen zur XML-Syntax zum Definieren von Eigenschaftsanimationen finden Sie unter Animationen Ressourcen .
Mögliche Auswirkungen auf die Leistung der Benutzeroberfläche
Animatoren, die die Benutzeroberfläche aktualisieren, verursachen zusätzliche Rendering-Arbeiten für jeden Frame in auf dem die Animation ausgeführt wird. Daher sollten Sie mit ressourcenintensiven Animationen sich negativ auf die Leistung Ihrer App auswirken kann.
Die zum Animieren der Benutzeroberfläche erforderlichen Arbeitsschritte werden im Animationsphase von der Rendering-Pipeline. Sie können herausfinden, ob sich Ihre Animationen App-Leistung steigern, indem Sie Profil-GPU-Rendering aktivieren und den Animationsbereich überwachen. Weitere Informationen finden Sie unter Profil-GPU-Rendering Schritt-für-Schritt-Anleitung.