Layoutänderungen mit einem Übergang animieren

Jetpack Compose
Jetpack Compose ist das empfohlene UI-Toolkit für Android. Informationen zum Verwenden von Animationen in Compose

Mit dem Übergangs-Framework von Android können Sie alle Arten von Bewegungen in Ihrer Benutzeroberfläche animieren, indem Sie die Start- und Endlayouts angeben. Sie können auswählen, welche Art von Animation Sie verwenden möchten, z. B. zum Ein- oder Ausblenden von Ansichten oder zum Ändern der Ansichtsgrößen. Das Übergangs-Framework bestimmt dann, wie die Animation vom Start- zum Endlayout erfolgt.

Das Übergangs-Framework umfasst die folgenden Funktionen:

  • Animationen auf Gruppenebene:Animationseffekte auf alle Ansichten in einer Ansichtshierarchie anwenden.
  • Integrierte Animationen:Vordefinierte Animationen für häufige Effekte wie Ausblenden oder Bewegung verwenden.
  • Unterstützung von Ressourcendateien:Ansichtshierarchien und integrierte Animationen aus Layout-Ressourcendateien laden.
  • Lebenszyklus-Callbacks:Rückrufe erhalten, die die Steuerung des Animations- und Hierarchieänderungsprozesses ermöglichen.

Der grundlegende Prozess zum Animieren zwischen zwei Layouts sieht so aus:

  1. Erstellen Sie ein Scene-Objekt für die Start- und Endlayouts. Die Szene des Startlayouts wird jedoch oft automatisch aus dem aktuellen Layout bestimmt.
  2. Erstellen Sie ein Transition Objekt, um den gewünschten Animationstyp zu definieren.
  3. Rufen Sie TransitionManager.go()auf. Das System führt dann die Animation aus, um die Layouts auszutauschen.

Das Diagramm in Abbildung 1 veranschaulicht die Beziehung zwischen Ihren Layouts, den Szenen, dem Übergang und der endgültigen Animation.

Abbildung 1 : Grundlegende Darstellung der Erstellung einer Animation durch das Übergangs-Framework.

Szene erstellen

In Szenen wird der Status einer Ansichtshierarchie gespeichert, einschließlich aller Ansichten und ihrer Attributwerte. Das Übergangs-Framework kann Animationen zwischen einer Start- und einer Endszene ausführen.

Sie können Szenen aus einer Layout-Ressourcendatei oder aus einer Gruppe von Ansichten in Ihrem Code erstellen. Die Startszene für den Übergang wird jedoch oft automatisch aus der aktuellen Benutzeroberfläche bestimmt.

In einer Szene können auch eigene Aktionen definiert werden, die ausgeführt werden, wenn Sie eine Szene ändern. Diese Funktion ist nützlich, um Ansichtseinstellungen zu bereinigen, nachdem Sie zu einer Szene gewechselt haben.

Szene aus einer Layout-Ressource erstellen

Sie können eine Scene-Instanz direkt aus einer Layout-Ressourcendatei erstellen. Verwenden Sie diese Methode, wenn die Ansichtshierarchie in der Datei weitgehend statisch ist. Die resultierende Szene stellt den Status der Ansichtshierarchie zum Zeitpunkt der Erstellung der Scene-Instanz dar. Wenn Sie die Ansichtshierarchie ändern, erstellen Sie die Szene neu. Das Framework erstellt die Szene aus der gesamten Ansichtshierarchie in der Datei. Sie können keine Szene aus einem Teil einer Layoutdatei erstellen.

Wenn Sie eine Scene-Instanz aus einer Layout-Ressourcendatei erstellen möchten, rufen Sie das Szenen-Root aus Ihrem Layout als ViewGroup ab. Rufen Sie dann die Scene.getSceneForLayout() Funktion mit dem Szenen-Root und der Ressourcen-ID der Layoutdatei auf, die die Ansichtshierarchie für die Szene enthält.

Layouts für Szenen definieren

Die Code-Snippets im Rest dieses Abschnitts zeigen, wie Sie zwei verschiedene Szenen mit demselben Szenen-Root-Element erstellen. Die Snippets zeigen auch, dass Sie mehrere unabhängige Scene-Objekte laden können, ohne dass sie miteinander in Beziehung stehen.

Das Beispiel besteht aus den folgenden Layoutdefinitionen:

  • Das Hauptlayout einer Aktivität mit einem Textlabel und einem untergeordneten FrameLayout.
  • Ein ConstraintLayout für die erste Szene mit zwei Textfeldern.
  • Ein ConstraintLayout für die zweite Szene mit denselben zwei Textfeldern in anderer Reihenfolge.

Das Beispiel ist so konzipiert, dass die gesamte Animation im untergeordneten Layout des Hauptlayouts für die Aktivität erfolgt. Das Textlabel im Hauptlayout bleibt statisch.

Das Hauptlayout für die Aktivität ist so definiert:

res/layout/activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/master_layout">
    <TextView
        android:id="@+id/title"
        ...
        android:text="Title"/>
    <FrameLayout
        android:id="@+id/scene_root">
        <include layout="@layout/a_scene" />
    </FrameLayout>
</LinearLayout>

Diese Layoutdefinition enthält ein Textfeld und ein untergeordnetes FrameLayout für das Szenen-Root. Das Layout für die erste Szene ist in der Hauptlayoutdatei enthalten. So kann die App es als Teil der anfänglichen Benutzeroberfläche anzeigen und auch in eine Szene laden, da das Framework nur eine vollständige Layoutdatei in eine Szene laden kann.

Das Layout für die erste Szene ist so definiert:

res/layout/a_scene.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/scene_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <TextView
        android:id="@+id/text_view1"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="Text Line 1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>
    <TextView
        android:id="@+id/text_view2"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="Text Line 2"
        app:layout_constraintTop_toBottomOf="@id/text_view1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Das Layout für die zweite Szene enthält dieselben zwei Textfelder mit denselben IDs in einer anderen Reihenfolge. Es ist so definiert:

res/layout/another_scene.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/scene_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <TextView
        android:id="@+id/text_view2"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="Text Line 2"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
    <TextView
        android:id="@+id/text_view1"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="Text Line 1"
        app:layout_constraintTop_toBottomOf="@id/text_view2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

Szenen aus Layouts generieren

Nachdem Sie Definitionen für die beiden Constraint-Layouts erstellt haben, können Sie für jedes eine Szene abrufen. So können Sie zwischen den beiden UI-Konfigurationen wechseln. Um eine Szene abzurufen, benötigen Sie einen Verweis auf das Szenen-Root und die Layout-Ressourcen-ID.

Das folgende Code-Snippet zeigt, wie Sie einen Verweis auf das Szenen-Root abrufen und zwei Scene-Objekte aus den Layoutdateien erstellen:

Kotlin

val sceneRoot: ViewGroup = findViewById(R.id.scene_root)
val aScene: Scene = Scene.getSceneForLayout(sceneRoot, R.layout.a_scene, this)
val anotherScene: Scene = Scene.getSceneForLayout(sceneRoot, R.layout.another_scene, this)

Java

Scene aScene;
Scene anotherScene;

// Create the scene root for the scenes in this app.
sceneRoot = (ViewGroup) findViewById(R.id.scene_root);

// Create the scenes.
aScene = Scene.getSceneForLayout(sceneRoot, R.layout.a_scene, this);
anotherScene =
    Scene.getSceneForLayout(sceneRoot, R.layout.another_scene, this);

In der App gibt es jetzt zwei Scene-Objekte, die auf Ansichtshierarchien basieren. Beide Szenen verwenden das Szenen-Root, das durch das FrameLayout-Element in res/layout/activity_main.xml definiert wird.

Szene im Code erstellen

Sie können auch eine Scene-Instanz in Ihrem Code aus einem ViewGroup-Objekt erstellen. Verwenden Sie diese Methode, wenn Sie die Ansichtshierarchien direkt in Ihrem Code ändern oder dynamisch generieren.

Wenn Sie eine Szene aus einer Ansichtshierarchie in Ihrem Code erstellen möchten, verwenden Sie den Scene(sceneRoot, viewHierarchy) Konstruktor. Das Aufrufen dieses Konstruktors entspricht dem Aufrufen der Scene.getSceneForLayout() Funktion, wenn Sie bereits eine Layoutdatei aufgeblasen haben.

Das folgende Code-Snippet zeigt, wie Sie eine Scene-Instanz aus dem Szenen-Root-Element und der Ansichtshierarchie für die Szene in Ihrem Code erstellen:

Kotlin

val sceneRoot = someLayoutElement as ViewGroup
val viewHierarchy = someOtherLayoutElement as ViewGroup
val scene: Scene = Scene(sceneRoot, viewHierarchy)

Java

Scene mScene;

// Obtain the scene root element.
sceneRoot = (ViewGroup) someLayoutElement;

// Obtain the view hierarchy to add as a child of
// the scene root when this scene is entered.
viewHierarchy = (ViewGroup) someOtherLayoutElement;

// Create a scene.
mScene = new Scene(sceneRoot, mViewHierarchy);

Szenenaktionen erstellen

Mit dem Framework können Sie benutzerdefinierte Szenenaktionen definieren, die vom System ausgeführt werden, wenn eine Szene aufgerufen oder verlassen wird. In vielen Fällen ist das Definieren benutzerdefinierter Szenenaktionen nicht erforderlich, da das Framework die Änderung zwischen Szenen automatisch animiert.

Szenenaktionen sind in folgenden Fällen nützlich:

  • Zum Animieren von Ansichten, die sich nicht in derselben Hierarchie befinden. Sie können Ansichten für die Start- und Endszenen mit Szenenaktionen für das Verlassen und Aufrufen animieren.
  • Zum Animieren von Ansichten, die vom Übergangs-Framework nicht automatisch animiert werden können, z. B. ListView-Objekte. Weitere Informationen finden Sie im Abschnitt zu Einschränkungen.

Wenn Sie benutzerdefinierte Szenenaktionen bereitstellen möchten, definieren Sie Ihre Aktionen als Runnable Objekte und übergeben Sie sie an die Scene.setExitAction() oder Scene.setEnterAction() Funktionen. Das Framework ruft die Funktion setExitAction() für die Startszene auf, bevor die Übergangsanimation ausgeführt wird, und die Funktion setEnterAction() für die Endszene, nachdem die Übergangsanimation ausgeführt wurde.

Übergang anwenden

Das Übergangs-Framework stellt den Stil der Animation zwischen Szenen mit einem Transition-Objekt dar. Sie können eine Transition mit integrierten Unterklassen wie AutoTransition und Fade instanziieren oder einen eigenen Übergang definieren. Anschließend können Sie die Animation zwischen Szenen ausführen, indem Sie die EndszeneScene und die Transition an TransitionManager.go() übergeben.

Der Übergangslebenszyklus ähnelt dem Aktivitätslebenszyklus und stellt die Übergangsstatus dar, die das Framework zwischen dem Start und dem Abschluss einer Animation überwacht. In wichtigen Lebenszyklusstatus ruft das Framework Callback-Funktionen auf, die Sie implementieren können, um die Benutzeroberfläche in verschiedenen Phasen des Übergangs anzupassen.

Übergang erstellen

Im vorherigen Abschnitt wurde beschrieben, wie Sie Szenen erstellen, die den Status verschiedener Ansichtshierarchien darstellen. Nachdem Sie die Start- und Endszenen definiert haben, zwischen denen Sie wechseln möchten, erstellen Sie ein Transition-Objekt, das eine Animation definiert. Mit dem Framework können Sie entweder einen integrierten Übergang in einer Ressourcendatei angeben und ihn in Ihrem Code aufblasen oder eine Instanz eines integrierten Übergangs direkt in Ihrem Code erstellen.

Tabelle 1 : Integrierte Übergangstypen.

Klasse Tag Effekt
AutoTransition <autoTransition/> Standardübergang. Blendet Ansichten aus, verschiebt und ändert ihre Größe und blendet sie dann wieder ein.
ChangeBounds <changeBounds/> Verschiebt und ändert die Größe von Ansichten.
ChangeClipBounds <changeClipBounds/> Erfasst die View.getClipBounds() vor und nach der Szenen änderung und animiert diese Änderungen während des Übergangs.
ChangeImageTransform <changeImageTransform/> Erfasst die Matrix eines ImageView vor und nach der Szenen änderung und animiert sie während des Übergangs.
ChangeScroll <changeScroll/> Erfasst die Scroll-Attribute von Zielen vor und nach der Szenen Änderung und animiert alle Änderungen.
ChangeTransform <changeTransform/> Erfasst die Skalierung und Drehung von Ansichten vor und nach der Szenenänderung und animiert diese Änderungen während des Übergangs.
Explode <explode/> Verfolgt Änderungen an der Sichtbarkeit von Zielansichten in den Start- und End Szenen und verschiebt Ansichten von den Rändern der Szene hinein oder hinaus.
Fade <fade/> fade_in blendet Ansichten ein.
fade_out blendet Ansichten aus.
fade_in_out (Standard) führt ein fade_out gefolgt von einem fade_in aus.
Slide <slide/> Verfolgt Änderungen an der Sichtbarkeit von Zielansichten in den Start- und End Szenen und verschiebt Ansichten von einem der Ränder der Szene hinein oder hinaus.

Übergangsinstanz aus einer Ressourcendatei erstellen

Mit dieser Methode können Sie die Übergangsdefinition ändern, ohne den Code Ihrer Aktivität zu ändern. Diese Methode ist auch nützlich, um komplexe Übergangsdefinitionen vom Anwendungscode zu trennen, wie im Abschnitt über Mehrere Übergänge angeben gezeigt.

So geben Sie einen integrierten Übergang in einer Ressourcendatei an:

  • Fügen Sie Ihrem Projekt das Verzeichnis res/transition/ hinzu.
  • Erstellen Sie in diesem Verzeichnis eine neue XML-Ressourcendatei.
  • Fügen Sie einen XML-Knoten für einen der integrierten Übergänge hinzu.

Die folgende Ressourcendatei gibt beispielsweise den Übergang Fade an:

res/transition/fade_transition.xml

<fade xmlns:android="http://schemas.android.com/apk/res/android" />

Das folgende Code-Snippet zeigt, wie Sie eine Transition-Instanz in Ihrer Aktivität aus einer Ressourcendatei aufblasen:

Kotlin

var fadeTransition: Transition =
    TransitionInflater.from(this)
                      .inflateTransition(R.transition.fade_transition)

Java

Transition fadeTransition =
        TransitionInflater.from(this).
        inflateTransition(R.transition.fade_transition);

Übergangsinstanz im Code erstellen

Diese Methode ist nützlich, um Übergangsobjekte dynamisch zu erstellen, wenn Sie die Benutzeroberfläche in Ihrem Code ändern, und um einfache integrierte Übergangsinstanzen mit wenigen oder keinen Parametern zu erstellen.

Wenn Sie eine Instanz eines integrierten Übergangs erstellen möchten, rufen Sie einen der öffentlichen Konstruktoren in den Unterklassen der Klasse Transition auf. Das folgende Code-Snippet erstellt beispielsweise eine Instanz des Übergangs Fade:

Kotlin

var fadeTransition: Transition = Fade()

Java

Transition fadeTransition = new Fade();

Übergang anwenden

Normalerweise wenden Sie einen Übergang an, um zwischen verschiedenen Ansichtshierarchien zu wechseln, wenn ein Ereignis eintritt, z. B. eine Nutzeraktion. Nehmen wir als Beispiel eine Such-App: Wenn der Nutzer einen Suchbegriff eingibt und auf die Suchschaltfläche tippt, wechselt die App zu einer Szene, die das Layout der Ergebnisse darstellt, und wendet dabei einen Übergang an, der die Suchschaltfläche ausblendet und die Suchergebnisse einblendet.

Wenn Sie eine Szene ändern und gleichzeitig einen Übergang anwenden möchten, wenn ein Ereignis in Ihrer Aktivität eintritt, rufen Sie die Klassenfunktion TransitionManager.go() mit der Endszene und der Übergangsinstanz auf, die für die Animation verwendet werden soll, wie im folgenden Snippet gezeigt:

Kotlin

TransitionManager.go(endingScene, fadeTransition)

Java

TransitionManager.go(endingScene, fadeTransition);

Das Framework ändert die Ansichtshierarchie im Szenen-Root mit der Ansichtshierarchie aus der Endszene, während die Animation ausgeführt wird, die durch die Übergangsinstanz angegeben wird. Die Startszene ist die Endszene aus dem letzten Übergang. Wenn kein vorheriger Übergang vorhanden ist, wird die Startszene automatisch aus dem aktuellen Status der Benutzeroberfläche bestimmt.

Wenn Sie keine Übergangsinstanz angeben, kann der Übergangsmanager einen automatischen Übergang anwenden, der in den meisten Situationen sinnvoll ist. Weitere Informationen finden Sie in der API-Referenz für die TransitionManager Klasse.

Bestimmte Zielansichten auswählen

Standardmäßig wendet das Framework Übergänge auf alle Ansichten in den Start- und Endszenen an. In einigen Fällen möchten Sie möglicherweise nur eine Animation auf eine Teilmenge der Ansichten in einer Szene anwenden. Mit dem Framework können Sie bestimmte Ansichten auswählen, die Sie animieren möchten. Das Framework unterstützt beispielsweise keine Animation von Änderungen an ListView-Objekten. Versuchen Sie daher nicht, sie während eines Übergangs zu animieren.

Jede Ansicht, die durch den Übergang animiert wird, wird als Ziel bezeichnet. Sie können nur Ziele auswählen, die Teil der Ansichtshierarchie sind, die mit einer Szene verknüpft ist.

Wenn Sie eine oder mehrere Ansichten aus der Liste der Ziele entfernen möchten, rufen Sie die removeTarget() Methode auf, bevor Sie den Übergang starten. Wenn Sie nur die von Ihnen angegebenen Ansichten zur Liste der Ziele hinzufügen möchten, rufen Sie die addTarget() Funktion auf. Weitere Informationen finden Sie in der API-Referenz für die Transition Klasse.

Mehrere Übergänge angeben

Um die bestmögliche Wirkung mit einer Animation zu erzielen, passen Sie sie an die Art der Änderungen an, die zwischen den Szenen auftreten. Wenn Sie beispielsweise zwischen Szenen einige Ansichten entfernen und andere hinzufügen, bietet eine Animation zum Aus- oder Einblenden einen deutlichen Hinweis darauf, dass einige Ansichten nicht mehr verfügbar sind. Wenn Sie Ansichten an andere Stellen auf dem Bildschirm verschieben, ist es besser, die Bewegung zu animieren, damit Nutzer die neue Position der Ansichten bemerken.

Sie müssen nicht nur eine Animation auswählen, da Sie mit dem Übergangs-Framework Animationseffekte in einem Übergangssatz kombinieren können, der eine Gruppe einzelner integrierter oder benutzerdefinierter Übergänge enthält.

Wenn Sie einen Übergangssatz aus einer Sammlung von Übergängen in XML definieren möchten, erstellen Sie eine Ressourcendatei im Verzeichnis res/transitions/ und listen Sie die Übergänge unter dem Element TransitionSet auf. Das folgende Snippet zeigt beispielsweise, wie Sie einen Übergangssatz angeben, der sich genauso verhält wie die Klasse AutoTransition:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
    android:transitionOrdering="sequential">
    <fade android:fadingMode="fade_out" />
    <changeBounds />
    <fade android:fadingMode="fade_in" />
</transitionSet>

Wenn Sie den Übergangssatz in Ihrem Code in ein TransitionSet Objekt aufblasen möchten, rufen Sie die TransitionInflater.from() Funktion in Ihrer Aktivität auf. Die TransitionSet Klasse wird von der Transition Klasse abgeleitet. Sie können sie also wie jede andere Transition Instanz mit einem Übergangsmanager verwenden.

Übergang ohne Szenen anwenden

Das Ändern von Ansichtshierarchien ist nicht die einzige Möglichkeit, die Benutzeroberfläche zu ändern. Sie können auch Änderungen vornehmen, indem Sie untergeordnete Ansichten in der aktuellen Hierarchie hinzufügen, ändern und entfernen.

Sie können beispielsweise eine Suchinteraktion mit einem einzelnen Layout implementieren. Beginnen Sie mit dem Layout, das ein Suchfeld und ein Suchsymbol enthält. Wenn Sie die Benutzeroberfläche so ändern möchten, dass die Ergebnisse angezeigt werden, entfernen Sie die Suchschaltfläche , wenn der Nutzer darauf tippt, indem Sie die ViewGroup.removeView() Funktion aufrufen, und fügen Sie die Suchergebnisse hinzu, indem Sie die ViewGroup.addView() Funktion aufrufen.

Sie können diese Methode verwenden, wenn die Alternative darin besteht, zwei fast identische Hierarchien zu haben. Anstatt zwei separate Layoutdateien für einen geringfügigen Unterschied in der Benutzeroberfläche zu erstellen und zu verwalten, können Sie eine Layoutdatei mit einer Ansichtshierarchie verwenden, die Sie im Code ändern.

Wenn Sie auf diese Weise Änderungen in der aktuellen Ansichtshierarchie vornehmen, müssen Sie keine Szene erstellen. Stattdessen können Sie einen Übergang zwischen zwei Status einer Ansichtshierarchie mit einem verzögerten Übergang erstellen und anwenden. Diese Funktion des Übergangs-Frameworks beginnt mit dem aktuellen Status der Ansichtshierarchie, erfasst Änderungen, die Sie an den Ansichten vornehmen, und wendet einen Übergang an, der die Änderungen animiert, wenn das System die Benutzeroberfläche neu zeichnet.

So erstellen Sie einen verzögerten Übergang innerhalb einer einzelnen Ansichtshierarchie:

  1. Wenn das Ereignis eintritt, das den Übergang auslöst, rufen Sie die TransitionManager.beginDelayedTransition() Funktion auf und geben Sie die übergeordnete Ansicht aller Ansichten an, die Sie ändern möchten, sowie den zu verwendenden Übergang. Das Framework speichert den aktuellen Status der untergeordneten Ansichten und ihre Attributwerte.
  2. Nehmen Sie die erforderlichen Änderungen an den untergeordneten Ansichten vor. Das Framework erfasst die Änderungen, die Sie an den untergeordneten Ansichten und ihren Attributen vornehmen.
  3. Wenn das System die Benutzeroberfläche gemäß Ihren Änderungen neu zeichnet, animiert das Framework die Änderungen zwischen dem ursprünglichen und dem neuen Status.

Das folgende Beispiel zeigt, wie Sie das Hinzufügen einer Textansicht zu einer Ansichtshierarchie mit einem verzögerten Übergang animieren. Das erste Snippet zeigt die Layoutdefinitionsdatei:

res/layout/activity_main.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/mainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <EditText
        android:id="@+id/inputText"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
    ...
</androidx.constraintlayout.widget.ConstraintLayout>

Das nächste Snippet zeigt den Code, der das Hinzufügen der Textansicht animiert:

MainActivity

Kotlin

setContentView(R.layout.activity_main)
val labelText = TextView(this).apply {
    text = "Label"
    id = R.id.text
}
val rootView: ViewGroup = findViewById(R.id.mainLayout)
val mFade: Fade = Fade(Fade.IN)
TransitionManager.beginDelayedTransition(rootView, mFade)
rootView.addView(labelText)

Java

private TextView labelText;
private Fade mFade;
private ViewGroup rootView;
...
// Load the layout.
setContentView(R.layout.activity_main);
...
// Create a new TextView and set some View properties.
labelText = new TextView(this);
labelText.setText("Label");
labelText.setId(R.id.text);

// Get the root view and create a transition.
rootView = (ViewGroup) findViewById(R.id.mainLayout);
mFade = new Fade(Fade.IN);

// Start recording changes to the view hierarchy.
TransitionManager.beginDelayedTransition(rootView, mFade);

// Add the new TextView to the view hierarchy.
rootView.addView(labelText);

// When the system redraws the screen to show this update,
// the framework animates the addition as a fade in.

Lebenszyklus-Callbacks für Übergänge definieren

Der Übergangslebenszyklus ähnelt dem Aktivitätslebenszyklus. Er stellt die Übergangsstatus dar, die das Framework während des Zeitraums zwischen einem Aufruf der Funktion TransitionManager.go() und dem Abschluss der Animation überwacht. In wichtigen Lebenszyklusstatus ruft das Framework Callbacks auf, die durch die Schnittstelle TransitionListener definiert werden.

Lebenszyklus-Callbacks für Übergänge sind beispielsweise nützlich, um den Wert eines Ansichtsattributs während einer Szenenänderung von der Start- in die Endansichtshierarchie zu kopieren. Sie können den Wert nicht einfach von der Startansicht in die Ansicht in der Endansichtshierarchie kopieren, da die Endansichtshierarchie erst aufgeblasen wird, wenn der Übergang abgeschlossen ist. Stattdessen müssen Sie den Wert in einer Variablen speichern und ihn dann in die Endansichtshierarchie kopieren, wenn das Framework den Übergang abgeschlossen hat. Wenn Sie benachrichtigt werden möchten, wenn der Übergang abgeschlossen ist, implementieren Sie die TransitionListener.onTransitionEnd() Funktion in Ihrer Aktivität.

Weitere Informationen finden Sie in der API-Referenz für die TransitionListener Klasse.

Einschränkungen

In diesem Abschnitt werden einige bekannte Einschränkungen des Übergangs-Frameworks aufgeführt:

  • Animationen, die auf eine SurfaceView angewendet werden, werden möglicherweise nicht richtig angezeigt. SurfaceView -Instanzen werden über einen Nicht-UI-Thread aktualisiert. Daher sind die Aktualisierungen möglicherweise nicht mit den Animationen anderer Ansichten synchron.
  • Einige bestimmte Übergangstypen erzeugen möglicherweise nicht den gewünschten Animationseffekt wenn sie auf eine TextureView angewendet werden.
  • Klassen, die AdapterView erweitern, z. B. ListView, verwalten ihre untergeordneten Ansichten auf eine Weise, die mit dem Übergangs-Framework nicht kompatibel ist. Wenn Sie versuchen, eine Ansicht basierend auf AdapterView zu animieren, reagiert das Display des Geräts möglicherweise nicht mehr.
  • Wenn Sie versuchen, die Größe einer TextView mit einer Animation zu ändern, wird der Text an eine neue Position verschoben, bevor die Größe des Objekts vollständig geändert wurde. Um dieses Problem zu vermeiden, animieren Sie die Größenänderung von Ansichten, die Text enthalten, nicht.