MotionLayout ist ein Layouttyp, mit dem Sie Bewegungen und Widget-Animationen in Ihrer App verwalten können. MotionLayout ist eine Unterklasse von ConstraintLayout und baut auf den umfangreichen Layoutfunktionen auf. Als Teil der ConstraintLayout-Bibliothek ist MotionLayout als Unterstützungsbibliothek verfügbar.
MotionLayout schließt die Lücke zwischen Layoutübergängen und komplexer Bewegungsverwaltung. Es bietet eine Mischung aus Funktionen aus dem Property Animation Framework, TransitionManager und CoordinatorLayout.
Mit MotionLayout können Sie nicht nur Übergänge zwischen Layouts beschreiben, sondern auch alle Layouteigenschaften animieren. Außerdem werden Suchfunktionen für Übergänge unterstützt. Das bedeutet, dass Sie jeden Punkt innerhalb des Übergangs basierend auf einer Bedingung, z. B. einer Touch-Eingabe, sofort anzeigen können. MotionLayout unterstützt auch keyframes, mit denen sich Übergänge vollständig an Ihre Anforderungen anpassen lassen.
MotionLayout ist vollständig deklarativ, d. h., Sie können beliebige Übergänge in XML beschreiben, unabhängig von ihrer Komplexität.
Designaspekte
MotionLayout dient dazu, UI-Elemente, mit denen Nutzer interagieren, wie Schaltflächen und Titelleisten, zu verschieben, ihre Größe anzupassen und zu animieren. Verwenden Sie in Ihrer App keine Bewegungen als unnötigen Spezialeffekt. Erklären Sie Nutzern damit, was Ihre App tut. Weitere Informationen zum Entwerfen Ihrer App mit Bewegung finden Sie im Abschnitt Bewegung verstehen des Artikels zu Material Design.
Erste Schritte
So verwenden Sie MotionLayout in Ihrem Projekt:
-
ConstraintLayout-Abhängigkeit hinzufügen:Wenn SieMotionLayoutin Ihrem Projekt verwenden möchten, fügen Sie derbuild.gradle-Datei Ihrer App die AbhängigkeitConstraintLayout2.0 hinzu. Wenn Sie AndroidX verwenden, fügen Sie die folgende Abhängigkeit hinzu:Cool
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.1" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.1" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.1") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.1") }
-
MotionLayout-Datei erstellen:MotionLayoutist eine Unterklasse vonConstraintLayout. Sie können also jede vorhandeneConstraintLayoutin eineMotionLayoutumwandeln, indem Sie den Klassennamen in Ihrer Layout-Ressourcendatei ersetzen, wie in den folgenden Beispielen gezeigt:AndroidX
<!-- before: ConstraintLayout --> <androidx.constraintlayout.widget.ConstraintLayout .../> <!-- after: MotionLayout --> <androidx.constraintlayout.motion.widget.MotionLayout .../>
Supportbibliothek
<!-- before: ConstraintLayout --> <android.support.constraint.ConstraintLayout .../> <!-- after: MotionLayout --> <android.support.constraint.motion.MotionLayout .../>
Hier ein vollständiges Beispiel für eine
MotionLayout-Datei, die das in Abbildung 1 dargestellte Layout definiert:AndroidX
<?xml version="1.0" encoding="utf-8"?> <!-- activity_main.xml --> <androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene_01" tools:showPaths="true"> <View android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:background="@color/colorAccent" android:text="Button" /> </androidx.constraintlayout.motion.widget.MotionLayout>
Supportbibliothek
<?xml version="1.0" encoding="utf-8"?> <!-- activity_main.xml --> <android.support.constraint.motion.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene_01" tools:showPaths="true"> <View android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:background="@color/colorAccent" android:text="Button" /> </android.support.constraint.motion.MotionLayout>
-
MotionScene erstellen:Im vorherigen
MotionLayout-Beispiel verweist dasapp:layoutDescription-Attribut auf eine Motion-Szene. Eine Bewegungsszene ist eine XML-Ressourcendatei. Innerhalb des Stammelements<MotionScene>enthält eine Bewegungsszene alle Bewegungsbeschreibungen für das entsprechende Layout. Damit Layoutinformationen von Bewegungsbeschreibungen getrennt bleiben, verweist jedesMotionLayoutauf eine separate Bewegungsszene. Die Definitionen in der Bewegungsszene haben Vorrang vor ähnlichen Definitionen in derMotionLayout.Hier ist eine Beispieldatei für eine Bewegungsszene, die die grundlegende horizontale Bewegung in Abbildung 1 beschreibt:
<?xml version="1.0" encoding="utf-8"?> <MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:motion="http://schemas.android.com/apk/res-auto"> <Transition motion:constraintSetStart="@+id/start" motion:constraintSetEnd="@+id/end" motion:duration="1000"> <OnSwipe motion:touchAnchorId="@+id/button" motion:touchAnchorSide="right" motion:dragDirection="dragRight" /> </Transition> <ConstraintSet android:id="@+id/start"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintStart_toStartOf="parent" motion:layout_constraintTop_toTopOf="parent" /> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginEnd="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintEnd_toEndOf="parent" motion:layout_constraintTop_toTopOf="parent" /> </ConstraintSet> </MotionScene>
Beachten Sie Folgendes:
-
<Transition>enthält die Basisdefinition der Bewegung.-
motion:constraintSetStartundmotion:constraintSetEndsind Verweise auf die Endpunkte der Bewegung. Diese Endpunkte werden später in der Bewegungsszene in den<ConstraintSet>-Elementen definiert. -
motion:durationgibt an, wie lange die Bewegung in Millisekunden dauert.
-
-
Mit
<OnSwipe>lassen sich Touchbedienungen für die Bewegung erstellen.-
motion:touchAnchorIdbezieht sich auf die Ansicht, in der Nutzer wischen und ziehen können. -
motion:touchAnchorSidebedeutet, dass die Ansicht von rechts gezogen wird. -
motion:dragDirectionbezieht sich auf die Vorwärts-Richtung des Ziehens. Beispiel:motion:dragDirection="dragRight"bedeutet, dass der Fortschritt zunimmt, wenn die Ansicht nach rechts gezogen wird.
-
-
<ConstraintSet>Hier definieren Sie die verschiedenen Einschränkungen, die Ihre Bewegung beschreiben. In diesem Beispiel ist für jeden Endpunkt der Bewegung eine<ConstraintSet>definiert. Diese Endpunkte werden mitapp:layout_constraintTop_toTopOf="parent"undapp:layout_constraintBottom_toBottomOf="parent"vertikal zentriert. Horizontal befinden sich die Endpunkte ganz links und rechts auf dem Bildschirm.
Weitere Informationen zu den verschiedenen Elementen, die in einer Bewegungsszene unterstützt werden, finden Sie in den Beispielen für MotionLayout.
-
Interpolierte Attribute
In einer Datei mit Bewegungsszenen können ConstraintSet-Elemente zusätzliche Attribute enthalten, die während des Übergangs interpoliert werden. Zusätzlich zu „position“ und „bounds“ werden die folgenden Attribute von MotionLayout interpoliert:
alphavisibilityelevationrotation,rotationX,rotationYtranslationX,translationY,translationZscaleX,scaleY
Benutzerdefinierte Attribute
Innerhalb eines <Constraint> können Sie mit dem <CustomAttribute>-Element einen Übergang für Attribute angeben, die nicht nur mit der Position oder View-Attributen zusammenhängen.
<Constraint android:id="@+id/button" ...> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#D81B60"/> </Constraint>
Ein <CustomAttribute> enthält zwei eigene Attribute:
motion:attributeNameist erforderlich und muss mit einem Objekt mit Get- und Set-Methoden übereinstimmen. Getter und Setter müssen einem bestimmten Muster entsprechen.backgroundColorwird beispielsweise unterstützt, da die Ansicht die zugrunde liegenden MethodengetBackgroundColor()undsetBackgroundColor()hat.- Welches Attribut Sie angeben müssen, hängt vom Werttyp ab. Wählen Sie einen der folgenden unterstützten Typen aus:
motion:customColorValuefür Farbenmotion:customIntegerValuefür Ganzzahlenmotion:customFloatValuefür Floatsmotion:customStringValuefür Stringsmotion:customDimensionfür Dimensionenmotion:customBooleanfür boolesche Werte
Wenn Sie ein benutzerdefiniertes Attribut angeben, definieren Sie Endpunktwerte sowohl in den Start- als auch in den Endelementen <ConstraintSet>.
Hintergrundfarbe ändern
Angenommen, Sie möchten, dass sich die Farben der Ansicht im Rahmen der Bewegung ändern, wie in Abbildung 2 dargestellt.
Fügen Sie jedem ConstraintSet-Element ein <CustomAttribute>-Element hinzu, wie im folgenden Code-Snippet dargestellt:
<ConstraintSet android:id="@+id/start"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintStart_toStartOf="parent" motion:layout_constraintTop_toTopOf="parent"> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#D81B60" /> </Constraint> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginEnd="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintEnd_toEndOf="parent" motion:layout_constraintTop_toTopOf="parent"> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#9999FF" /> </Constraint> </ConstraintSet>
Zusätzliche MotionLayout-Attribute
Zusätzlich zu den Attributen im vorherigen Beispiel hat MotionLayout weitere Attribute, die Sie möglicherweise angeben möchten:
app:applyMotionScene="boolean"gibt an, ob die Bewegungsszene angewendet werden soll. Der Standardwert für dieses Attribut isttrue.app:showPaths="boolean"gibt an, ob die Bewegungspfade während der Bewegung angezeigt werden sollen. Der Standardwert für dieses Attribut istfalse.- Mit
app:progress="float"können Sie den Fortschritt der Umstellung explizit angeben. Sie können jeden Gleitkommawert von0(Anfang des Übergangs) bis1(Ende des Übergangs) verwenden. - Mit
app:currentState="reference"können Sie einen bestimmtenConstraintSetangeben. - Mit
app:motionDebugkönnen Sie zusätzliche Informationen zur Fehlerbehebung für die Bewegung aufrufen. Mögliche Werte sind"SHOW_PROGRESS","SHOW_PATH"und"SHOW_ALL".
Weitere Informationen
Weitere Informationen zu MotionLayout finden Sie in den folgenden Ressourcen:
- Advanced Android in Kotlin 03.2: Animation with MotionLayout
- Beispiele für MotionLayout
- MotionLayout/ConstraintLayout-Beispiele auf GitHub
- Einführung in MotionLayout (Teil I)
- Einführung in MotionLayout (Teil II)
- Einführung in MotionLayout (Teil III)
- Einführung in MotionLayout (Teil IV)