MotionLayout
ist ein Layouttyp, mit dem Sie Bewegungen und Widget-Animationen in Ihrer App verwalten können. MotionLayout
ist eine Unterklasse von ConstraintLayout
und nutzt dessen umfangreiche Layoutfunktionen. Als Teil der ConstraintLayout
-Bibliothek ist MotionLayout
als Unterstützungsbibliothek verfügbar.
MotionLayout
schließt die Lücke zwischen Layoutübergängen und komplexen Bewegungsverarbeitungen und bietet eine Mischung aus Funktionen für das Eigenschaftsanimations-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 wie 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. Hilf Nutzern dabei, deine App zu verstehen. 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 SieMotionLayout
in Ihrem Projekt verwenden möchten, fügen Sie derbuild.gradle
-Datei Ihrer App die AbhängigkeitConstraintLayout
2.0 hinzu. Wenn Sie AndroidX verwenden, fügen Sie die folgende Abhängigkeit hinzu:Groovy
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.0-beta01" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.0-beta01") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01") }
-
MotionLayout
-Datei erstellen:MotionLayout
ist eine Unterklasse vonConstraintLayout
. Sie können also jede vorhandeneConstraintLayout
in eineMotionLayout
umwandeln, 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 gezeigte 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 jedesMotionLayout
auf 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:constraintSetStart
undmotion:constraintSetEnd
sind Verweise auf die Endpunkte der Bewegung. Diese Endpunkte werden später in der Bewegungsszene in den<ConstraintSet>
-Elementen definiert. -
motion:duration
gibt an, wie lange die Bewegung in Millisekunden dauert.
-
-
Mit
<OnSwipe>
lassen sich Touchbedienungen für die Bewegung erstellen.-
motion:touchAnchorId
bezieht sich auf die Ansicht, in der Nutzer wischen und ziehen können. -
motion:touchAnchorSide
bedeutet, dass die Ansicht von rechts gezogen wird. -
motion:dragDirection
bezieht 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.
Genauere Informationen zu den verschiedenen Elementen, die von einer Bewegungsszene unterstützt werden, finden Sie in den MotionLayout-Beispielen.
-
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:
alpha
visibility
elevation
rotation
,rotationX
,rotationY
translationX
,translationY
,translationZ
scaleX
,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:attributeName
ist erforderlich und muss einem Objekt mit Getter- und Setter-Methoden entsprechen. Getter und Setter müssen einem bestimmten Muster entsprechen.backgroundColor
wird beispielsweise unterstützt, da die Ansicht die zugrunde liegenden MethodengetBackgroundColor()
undsetBackgroundColor()
hat.- Das andere Attribut, das Sie angeben müssen, basiert auf dem Werttyp. Wählen Sie einen der folgenden unterstützten Typen aus:
motion:customColorValue
für Farbenmotion:customIntegerValue
für Ganzzahlenmotion:customFloatValue
für Floatsmotion:customStringValue
für Stringsmotion:customDimension
für Dimensionenmotion:customBoolean
für boolesche Werte
Wenn du ein benutzerdefiniertes Attribut angibst, definiere Endpunktwerte in den <ConstraintSet>
-Elementen (start und end).
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 Übergangsfortschritt explizit angeben. Sie können einen beliebigen Gleitkommawert von0
(Beginn des Übergangs) bis1
(Ende des Übergangs) verwenden. - Mit
app:currentState="reference"
können Sie einen bestimmtenConstraintSet
angeben. - Mit
app:motionDebug
kö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:
- Erweiterte Android-Versionen in Kotlin 03.2: Animation mit MotionLayout
- MotionLayout-Beispiele
- 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)