Attributanimation – Übersicht

Schreiben Sie jetzt
Jetpack Compose ist das empfohlene UI-Toolkit für Android. Weitere Informationen zur Verwendung von Animationen in „Compose“
<ph type="x-smartling-placeholder"></ph> animate*AsState →

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.

Abbildung 1: Beispiel für eine lineare Animation

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.

Abbildung 2: Beispiel für eine nicht lineare Animation

Sehen wir uns genauer an, wie die wichtigen Komponenten des Animationen wie die oben dargestellten berechnet. Abbildung 3 zeigt, wie die Hauptklassen miteinander arbeiten.

Abbildung 3: Berechnung von Animationen

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:

Tabelle 1 Animatoren

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:

Tabelle 2: Evaluierende

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.

Tabelle 3 Interpolatoren

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 die ObjectAnimator 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 beispielsweise foo, müssen Sie haben eine setFoo()-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 der ObjectAnimator-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 von get<PropertyName>(). Lautet der Eigenschaftsname beispielsweise foo, du benötigst eine getFoo()-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 Sie targetObject.setPropName(float) und targetObject.getPropName() wenn Sie die folgende ObjectAnimator 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 der onAnimationUpdate() 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() und setTranslationX() 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:

  1. bounceAnim wird abgespielt.
  2. squashAnim1, squashAnim2, stretchAnim1 und stretchAnim2.
  3. bounceBackAnim wird abgespielt.
  4. 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
  • ValueAnimator.AnimatorUpdateListener
    • onAnimationUpdate() wird bei jedem Frame der Animation aufgerufen. Dieses Ereignis überwachen, um die von ValueAnimator während eines Animation. Fragen Sie das ValueAnimator-Objekt ab, um den Wert zu verwenden an das Ereignis übergeben werden, um den aktuellen animierten Wert mit der Methode getAnimatedValue() abzurufen. Die Implementierung dieser Listener ist erforderlich, wenn Sie ValueAnimator 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() und setTranslationX() 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:

res/xml/animate_scale.xml

<?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 und translationY: 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 und rotationY: Diese Properties Sie können die Drehung in 2D (Eigenschaft rotation) und 3D um den Drehpunkt steuern.
  • scaleX und scaleY: Diese Eigenschaften steuern die 2D-Skalierung eines Ansicht um seinen Drehpunkt herum.
  • pivotX und pivotY: 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 und y: 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:

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.