Benutzerdefinierte Übergangsanimation erstellen

Compose ausprobieren
Jetpack Compose ist das empfohlene UI-Toolkit für Android. Informationen zum Hinzufügen von Animationen in der Google Messages App

Mit einem benutzerdefinierten Übergang können Sie eine Animation erstellen, die in keiner der integrierten Übergangsklassen verfügbar ist. Sie können beispielsweise einen benutzerdefinierten Übergang definieren, bei dem die Vordergrundfarbe von Text und Eingabefeldern grau wird, um anzuzeigen, dass die Felder auf dem neuen Bildschirm deaktiviert sind. Durch diese Art von Änderung können Nutzer die von Ihnen deaktivierten Felder sehen.

Bei einem benutzerdefinierten Übergang, wie einem der vordefinierten Übergangstypen, werden Animationen auf untergeordnete Ansichten sowohl der Anfangs- als auch der Endszene angewendet. Im Gegensatz zu integrierten Übergangstypen müssen Sie jedoch den Code bereitstellen, mit dem Property-Werte erfasst und Animationen generiert werden. Sie können auch eine Teilmenge der Zielansichten für die Animation definieren.

Auf dieser Seite erfahren Sie, wie Sie Property-Werte erfassen und Animationen generieren, um benutzerdefinierte Übergänge zu erstellen.

Übergangsklasse erweitern

Wenn Sie einen benutzerdefinierten Übergang erstellen möchten, fügen Sie Ihrem Projekt eine Klasse hinzu, die die Klasse Transition erweitert, und überschreiben Sie die Funktionen im folgenden Snippet:

Kotlin

class CustomTransition : Transition() {

    override fun captureStartValues(transitionValues: TransitionValues) {}

    override fun captureEndValues(transitionValues: TransitionValues) {}

    override fun createAnimator(
        sceneRoot: ViewGroup,
        startValues: TransitionValues?,
        endValues: TransitionValues?
    ): Animator? {}

}

Java

public class CustomTransition extends Transition {

    @Override
    public void captureStartValues(TransitionValues values) {}

    @Override
    public void captureEndValues(TransitionValues values) {}

    @Override
    public Animator createAnimator(ViewGroup sceneRoot,
                                   TransitionValues startValues,
                                   TransitionValues endValues) {}
}

In den folgenden Abschnitten wird beschrieben, wie Sie diese Funktionen überschreiben.

Werte für Ansichtsattribute erfassen

Für Übergangsanimationen wird das Attributanimationssystem verwendet, das im Hilfeartikel Attributanimation – Übersicht beschrieben wird. Bei Property-Animationen ändert sich eine Ansichtseigenschaft über einen bestimmten Zeitraum von einem Startwert in einen Endwert. Das Framework muss also sowohl den Start- als auch den Endwert der Property haben, um die Animation zu erstellen.

Für eine Property-Animation ist jedoch in der Regel nur ein kleiner Teil aller Property-Werte der Ansicht erforderlich. Für eine Farbanimation sind beispielsweise Werte für die Farbeigenschaft erforderlich, während für eine Bewegungsanimation Werte für die Positionierungseigenschaft benötigt werden. Da die für eine Animation erforderlichen Attributwerte für einen Übergang spezifisch sind, bietet das Übergangs-Framework nicht jeden Attributwert für einen Übergang an. Stattdessen ruft das Framework Callback-Funktionen auf, die es ermöglichen, nur die erforderlichen Property-Werte zu erfassen und im Framework zu speichern.

Startwerte erfassen

Implementieren Sie die Funktion captureStartValues(transitionValues), um die Startansichtswerte an das Framework zu übergeben. Das Framework ruft diese Funktion für jede Ansicht in der Startszene auf. Das Funktionsargument ist ein TransitionValues-Objekt, das eine Referenz auf die Datenansicht und eine Map-Instanz enthält, in der Sie die gewünschten Datenansichtswerte speichern können. Rufen Sie diese Property-Werte in Ihrer Implementierung ab und geben Sie sie an das Framework zurück, indem Sie sie in der Karte speichern.

Damit der Schlüssel für einen Property-Wert nicht mit anderen TransitionValues-Schlüsseln in Konflikt steht, verwenden Sie das folgende Benennungsschema:

package_name:transition_name:property_name

Das folgende Snippet zeigt eine Implementierung der Funktion captureStartValues():

Kotlin

class CustomTransition : Transition() {

    // Define a key for storing a property value in
    // TransitionValues.values with the syntax
    // package_name:transition_class:property_name to avoid collisions
    private val PROPNAME_BACKGROUND = "com.example.android.customtransition:CustomTransition:background"

    override fun captureStartValues(transitionValues: TransitionValues) {
        // Call the convenience method captureValues
        captureValues(transitionValues)
    }

    // For the view in transitionValues.view, get the values you
    // want and put them in transitionValues.values
    private fun captureValues(transitionValues: TransitionValues) {
        // Get a reference to the view
        val view = transitionValues.view
        // Store its background property in the values map
        transitionValues.values[PROPNAME_BACKGROUND] = view.background
    }

    ...

}

Java

public class CustomTransition extends Transition {

    // Define a key for storing a property value in
    // TransitionValues.values with the syntax
    // package_name:transition_class:property_name to avoid collisions
    private static final String PROPNAME_BACKGROUND =
            "com.example.android.customtransition:CustomTransition:background";

    @Override
    public void captureStartValues(TransitionValues transitionValues) {
        // Call the convenience method captureValues
        captureValues(transitionValues);
    }


    // For the view in transitionValues.view, get the values you
    // want and put them in transitionValues.values
    private void captureValues(TransitionValues transitionValues) {
        // Get a reference to the view
        View view = transitionValues.view;
        // Store its background property in the values map
        transitionValues.values.put(PROPNAME_BACKGROUND, view.getBackground());
    }
    ...
}

Endwerte erfassen

Das Framework ruft die Funktion captureEndValues(TransitionValues) einmal für jede Zielansicht in der Endszene auf. In allen anderen Punkten funktioniert captureEndValues() genauso wie captureStartValues().

Das folgende Code-Snippet zeigt eine Implementierung der Funktion captureEndValues():

Kotlin

override fun captureEndValues(transitionValues: TransitionValues) {
    captureValues(transitionValues)
}

Java

@Override
public void captureEndValues(TransitionValues transitionValues) {
    captureValues(transitionValues);
}

In diesem Beispiel rufen sowohl die Funktion captureStartValues() als auch die Funktion captureEndValues() captureValues() auf, um Werte abzurufen und zu speichern. Die Ansichtseigenschaft, die von captureValues() abgerufen wird, ist dieselbe, hat aber in der Start- und Endszene unterschiedliche Werte. Das Framework verwaltet separate Karten für den Anfangs- und Endstatus einer Ansicht.

Benutzerdefinierte Animatoren erstellen

Wenn Sie die Änderungen an einer Ansicht zwischen ihrem Status in der Start- und der Endszene animieren möchten, müssen Sie einen Animator bereitstellen, indem Sie die Funktion createAnimator() überschreiben. Wenn das Framework diese Funktion aufruft, werden die Stammansicht der Szene und die TransitionValues-Objekte übergeben, die die von Ihnen erfassten Start- und Endwerte enthalten.

Wie oft das Framework die Funktion createAnimator() aufruft, hängt von den Änderungen ab, die zwischen der Start- und der Endszene auftreten.

Angenommen, Sie haben eine Ein- oder Ausblendungsanimation als benutzerdefinierten Übergang implementiert. Wenn die Startszene fünf Ziele hat, von denen zwei aus der Endszene entfernt werden, und die Endszene die drei Ziele aus der Start- sowie ein neues Ziel hat, ruft das Framework createAnimator() sechsmal auf. Drei der Aufrufe animieren das Ein- und Ausblenden der Ziele, die in beiden Szenenobjekten bleiben. Zwei weitere Aufrufe animieren das Ausblenden der Ziele, die aus der Endszene entfernt wurden. Mit einem Aufruf wird das Einblenden des neuen Ziels in der Endszene animiert.

Für Zielansichten, die sowohl in der Start- als auch in der Endszene vorhanden sind, stellt das Framework sowohl für das startValues- als auch für das endValues-Argument ein TransitionValues-Objekt bereit. Für Zielansichten, die nur in der Start- oder Endszene vorhanden sind, stellt das Framework ein TransitionValues-Objekt für das entsprechende Argument und null für das andere bereit.

Wenn Sie die Funktion createAnimator(ViewGroup, TransitionValues, TransitionValues) beim Erstellen eines benutzerdefinierten Übergangs implementieren möchten, verwenden Sie die erfassten Werte der Ansichtseigenschaften, um ein Animator-Objekt zu erstellen und an das Framework zurückzugeben. Eine Beispielimplementierung finden Sie in der Klasse ChangeColor im Beispiel Benutzerdefinierte Übergänge. Weitere Informationen zu Property-Animatoren finden Sie unter Property-Animation.

Benutzerdefinierte Umstellung anwenden

Benutzerdefinierte Übergänge funktionieren genauso wie integrierte Übergänge. Sie können einen benutzerdefinierten Übergang mit einem Übergangsmanager anwenden, wie unter Übergang anwenden beschrieben.