Bewegungen und Widget-Animationen mit MotionLayout verwalten

MotionLayout ist ein Layouttyp, mit dem Sie Bewegungs- und Widget-Animationen in Ihrer App verwalten können. MotionLayout ist eine abgeleitete Klasse von ConstraintLayout und baut auf seinen Layoutfunktionen. Als Teil der ConstraintLayout Bibliothek MotionLayout ist als Supportbibliothek verfügbar.

MotionLayout schließt die Lücke zwischen Layoutübergängen und komplexen Bewegungen und bietet eine Mischung aus Funktionen zwischen den Eigenschaften Framework TransitionManager und CoordinatorLayout

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder"> <ph type="x-smartling-placeholder">
</ph> Abbildung 1: Einfache Touchbedienung.

Mit MotionLayout können Sie nicht nur Übergänge zwischen Layouts beschreiben, Layouteigenschaften zu animieren. Darüber hinaus unterstützt es von Natur aus suchbare Übergänge. Das heißt, Sie können jeden Punkt innerhalb des Übergangs sofort anzeigen. wie z. B. Eingabe per Berührung. MotionLayout unterstützt auch Keyframes erstellen, die vollständig benutzerdefinierte Übergänge ermöglichen.

MotionLayout ist vollständig deklarativ, d. h., Sie können alle Übergänge in XML schreiben, ganz egal, wie komplex sie sind.

Designüberlegungen

MotionLayout ist dazu gedacht, UI-Elemente zu verschieben, in der Größe zu ändern und zu animieren, Nutzende interagieren, wie z. B. Schaltflächen und Titelleisten. Verwenden Sie in Ihrer App keine Bewegungen als grundloser Spezialeffekt. Damit können Sie Nutzern vermitteln, worum es in Ihrer App geht. was Sie tun. Weitere Informationen zum Entwerfen Ihrer App mit Bewegungselementen finden Sie in der Material Design-Abschnitt Verstehen Bewegung.

Erste Schritte

Führen Sie die folgenden Schritte aus, um MotionLayout in Ihrem Projekt zu verwenden.

  1. Fügen Sie die zu verwendende ConstraintLayout-Abhängigkeit hinzu: MotionLayout in Ihrem Projekt haben, fügen Sie den ConstraintLayout 2.0-Abhängigkeit von der build.gradle-Datei. Wenn Sie AndroidX verwenden, fügen Sie den folgende Abhängigkeit:

    Cool

    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")
    }
    
  2. MotionLayout-Datei erstellen: MotionLayout ist eine abgeleitete Klasse von ConstraintLayout, sodass Sie jedes beliebige Element bestehende ConstraintLayout in MotionLayout um Ersetzen Sie den Klassennamen in Ihrer Layoutressourcendatei, wie in den folgende Beispiele:

    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 definiert das in Abbildung 1 gezeigte Layout:

    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>
            
  3. MotionScene erstellen: im vorherigen MotionLayout verweist beispielsweise das Attribut app:layoutDescription auf ein Bewegungsszene. Eine Bewegungsszene ist eine XML-Ressourcendatei. Im <MotionScene> Stammelement enthält, enthält eine Bewegungsszene alle Bewegungsbeschreibungen des das entsprechende Layout. Um Layoutinformationen von Bewegungselementen zu trennen enthält, verweist jeder MotionLayout auf eine separate Bewegung. Szene. Die Definitionen in der Bewegungsszene haben Vorrang vor allen ähnlichen finden Sie in den MotionLayout.

    Hier ist ein Beispiel für eine Animationsszenendatei, die die grundlegenden horizontalen Bewegung in Abbildung 1:

    <?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 und motion:constraintSetEnd beziehen sich auf die Endpunkte der Bewegung. Diese Endpunkte sind in den <ConstraintSet>-Elemente später in der Bewegungsszene.

      • motion:duration gibt die Anzahl der Millisekunden an. bis die Bewegung abgeschlossen ist.

    • <OnSwipe> kannst du eine Touchbedienung für die Bewegung erstellen.

      • motion:touchAnchorId bezieht sich auf die Ansicht, die der Nutzer sehen kann Wischen und ziehen.

      • motion:touchAnchorSide steht für wird von der rechten Seite gezogen.

      • motion:dragDirection bezieht sich auf den Fortschritt Ziehrichtung. Beispiel: motion:dragDirection="dragRight" steht für Fortschritt nimmt zu, wenn die Ansicht nach rechts gezogen wird.

    • <ConstraintSet> definieren Sie die verschiedenen Beschränkungen, die Ihre Bewegung beschreiben. In diesem Beispiel ist eine <ConstraintSet> definiert für jeden Endpunkt deiner Bewegung. Diese Endpunkte sind vertikal zentriert mit app:layout_constraintTop_toTopOf="parent" und app:layout_constraintBottom_toBottomOf="parent". Horizontal befinden sich die Endpunkte am linken und rechten Rand des Bildschirm.

    Für einen detaillierteren Blick auf die verschiedenen Elemente einer Bewegungsszene finden Sie in der MotionLayout-Beispiele.

Interpolierte Attribute

Innerhalb einer Bewegungsszenendatei können ConstraintSet-Elemente zusätzliche Attribute, die beim Übergang interpoliert werden. Neben Positions- und Grenzen gesetzt sind, werden die folgenden Attribute von MotionLayout interpoliert:

  • alpha
  • visibility
  • elevation
  • rotation, rotationX, rotationY
  • translationX, translationY, translationZ
  • scaleX, scaleY

Benutzerdefinierte Attribute

Innerhalb einer <Constraint> können Sie mit dem <CustomAttribute>-Element angeben, ein Übergang für Attribute, die nicht nur mit Position oder View zusammenhängen Attribute.

<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. Der Getter und Setter müssen einem bestimmten Muster entsprechen. Für Beispiel: backgroundColor wird unterstützt, da der Ansicht zugrunde liegende getBackgroundColor()- und setBackgroundColor()-Methoden.
  • Das andere Attribut, das Sie angeben müssen, basiert auf dem Werttyp. Wähle aus die folgenden unterstützten Typen: <ph type="x-smartling-placeholder">
      </ph>
    • motion:customColorValue für Farben
    • motion:customIntegerValue für Ganzzahlen
    • motion:customFloatValue für Gleitkommazahlen
    • motion:customStringValue für Strings
    • motion:customDimension für Dimensionen
    • motion:customBoolean für boolesche Werte

Definieren Sie beim Angeben eines benutzerdefinierten Attributs die Endpunktwerte in den Start- und <ConstraintSet>-Endelemente.

Hintergrundfarbe ändern

Nehmen wir noch einmal an, Sie möchten, dass sich die Farben der Ansicht ändern. als Teil seiner Bewegung, wie in Abbildung 2 dargestellt.

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder"> <ph type="x-smartling-placeholder">
</ph> Abbildung 2: Die Ansicht ändert ihre Hintergrundfarbe, während sie sich bewegt.

Fügen Sie jedem ConstraintSet-Element ein <CustomAttribute>-Element hinzu, wie in das folgende Code-Snippet:

<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 andere Attribute Attribute, die Sie angeben können:

  • app:applyMotionScene="boolean" gibt an, ob die Bewegungsszene angewendet werden soll. Der Standardwert für dieses Attribut ist true.
  • app:showPaths="boolean" gibt an, ob die Bewegungspfade die Bewegung läuft. Der Standardwert für dieses Attribut ist false.
  • Mit app:progress="float" können Sie den Übergangsfortschritt explizit angeben. Ich kann einen beliebigen Gleitkommawert von 0 (Beginn des Übergangs) bis 1 verwenden (Ende des Übergangs).
  • Mit app:currentState="reference" können Sie eine bestimmte ConstraintSet angeben.
  • Mit app:motionDebug können Sie zusätzliche Debug-Informationen zur Bewegung. Mögliche Werte sind "SHOW_PROGRESS", "SHOW_PATH" und "SHOW_ALL".

Weitere Informationen

Weitere Informationen zu MotionLayout finden Sie in den folgenden Ressourcen: