MotionLayout
è un tipo di layout che ti consente di gestire le animazioni di movimento e widget nella tua app.
MotionLayout
è una sottoclasse di
ConstraintLayout
e si basa sulle sue funzionalità di layout. Nell'ambito della libreria ConstraintLayout
, MotionLayout
è disponibile come libreria di supporto.
MotionLayout
colma il divario tra le transizioni di layout e la gestione complessa dei movimenti, offrendo un mix di funzionalità tra il framework di animazione delle proprietà, TransitionManager
e CoordinatorLayout
.
Oltre a descrivere le transizioni tra i layout, MotionLayout
consente di animare qualsiasi proprietà del layout. Inoltre, supporta intrinsecamente le transizioni scorrevoli. Ciò significa che puoi mostrare immediatamente qualsiasi punto all'interno della transizione in base a una condizione, ad esempio l'input tocco. MotionLayout
supporta anche i keyframe, che consentono transizioni completamente personalizzate in base alle tue esigenze.
MotionLayout
è un valore completamente dichiarativo, vale a dire che puoi descrivere qualsiasi transizione in XML, indipendentemente dalla complessità.
Considerazioni sul design
MotionLayout
è progettato per spostare, ridimensionare e animare gli elementi dell'interfaccia utente con cui interagiscono gli utenti, come pulsanti e barre dei titoli. Non utilizzare il movimento nella tua app come
effetto speciale senza costi. Usali per aiutare gli utenti a capire cosa
fa la tua app. Per saperne di più sulla progettazione dell'app con il movimento, consulta la sezione Informazioni sul movimento di Material Design.
Inizia
Segui questi passaggi per iniziare a utilizzare MotionLayout
nel tuo progetto.
-
Aggiungi la dipendenza
ConstraintLayout
: per utilizzareMotionLayout
nel tuo progetto, aggiungi la dipendenzaConstraintLayout
2.0 al filebuild.gradle
della tua app. Se utilizzi AndroidX, aggiungi la seguente dipendenza:Alla moda
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") }
-
Crea un file
MotionLayout
:MotionLayout
è una sottoclasse diConstraintLayout
, quindi puoi trasformare qualsiasiConstraintLayout
esistente in unMotionLayout
sostituendo il nome della classe nel file delle risorse di layout, come mostrato negli esempi seguenti:AndroidX
<!-- before: ConstraintLayout --> <androidx.constraintlayout.widget.ConstraintLayout .../> <!-- after: MotionLayout --> <androidx.constraintlayout.motion.widget.MotionLayout .../>
Libreria di supporto
<!-- before: ConstraintLayout --> <android.support.constraint.ConstraintLayout .../> <!-- after: MotionLayout --> <android.support.constraint.motion.MotionLayout .../>
Ecco un esempio completo di un file
MotionLayout
, che definisce il layout mostrato nella figura 1: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>
Libreria di supporto
<?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>
-
Crea una scena animata: nell'esempio
MotionLayout
precedente, l'attributoapp:layoutDescription
fa riferimento a una scena animata. Una scena in movimento è un file di risorse XML. All'interno del suo elemento radice<MotionScene>
, una scena animata contiene tutte le descrizioni dei movimenti per il layout corrispondente. Per mantenere separate le informazioni sul layout dalle descrizioni del movimento, ogniMotionLayout
fa riferimento a una scena di movimento distinta. Le definizioni nella scena in movimento hanno la precedenza su eventuali definizioni simili nelMotionLayout
.Ecco un esempio di file di scena con movimento che descrive il movimento orizzontale di base nella figura 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>
Nota:
-
<Transition>
contiene la definizione di base del movimento.-
motion:constraintSetStart
emotion:constraintSetEnd
sono riferimenti ai punti finali del movimento. Questi endpoint sono definiti negli elementi<ConstraintSet>
più avanti nella scena di movimento. -
motion:duration
specifica il numero di millisecondi necessari per il completamento del movimento.
-
-
<OnSwipe>
consente di creare controlli touch per il movimento.-
motion:touchAnchorId
si riferisce alla visualizzazione che l'utente può scorrere e trascinare. -
motion:touchAnchorSide
indica che la visualizzazione viene trascinata dal lato destro. -
motion:dragDirection
si riferisce alla direzione di avanzamento del trascinamento. Ad esempio,motion:dragDirection="dragRight"
indica che il progresso aumenta man mano che la visualizzazione viene trascinata verso destra.
-
-
<ConstraintSet>
è dove definisci i vari vincoli che descrivono il movimento. In questo esempio, viene definito un<ConstraintSet>
per ogni endpoint del movimento. Questi endpoint sono centrati verticalmente utilizzandoapp:layout_constraintTop_toTopOf="parent"
eapp:layout_constraintBottom_toBottomOf="parent"
. Orizzontalmente, i punti finali si trovano ai lati più a sinistra e a destra dello schermo.
Per una visione più dettagliata dei vari elementi supportati da una scena di movimento, vedi gli esempi di MotionLayout.
-
Attributi interpolati
All'interno di un file di scena animata, gli elementi ConstraintSet
possono contenere attributi aggiuntivi che vengono interpolati durante la transizione. Oltre a position e
bounds, i seguenti attributi vengono interpolati da MotionLayout
:
alpha
visibility
elevation
rotation
,rotationX
erotationY
translationX
,translationY
etranslationZ
scaleX
,scaleY
Attributi personalizzati
All'interno di un <Constraint>
, puoi utilizzare l'elemento <CustomAttribute>
per specificare
una transizione per gli attributi che non sono semplicemente correlati alla posizione o agli attributi View
.
<Constraint android:id="@+id/button" ...> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#D81B60"/> </Constraint>
Un <CustomAttribute>
contiene due attributi:
motion:attributeName
è obbligatorio e deve corrispondere a un oggetto con metodi getter e setter. Il getter e il setter devono corrispondere a un pattern specifico. Ad esempio,backgroundColor
è supportato, poiché la visualizzazione ha metodigetBackgroundColor()
esetBackgroundColor()
sottostanti.- L'altro attributo da fornire si basa sul tipo di valore. Scegli tra i seguenti tipi supportati:
motion:customColorValue
per i colorimotion:customIntegerValue
per numeri interimotion:customFloatValue
per i floatmotion:customStringValue
per le stringhemotion:customDimension
per le dimensionimotion:customBoolean
per i valori booleani
Quando specifichi un attributo personalizzato, definisci i valori di endpoint sia negli elementi <ConstraintSet>
inizio che
<ConstraintSet>
fine.
Cambia il colore dello sfondo
Basandoti sull'esempio precedente, supponiamo che tu voglia che i colori della visualizzazione cambino nel corso del movimento, come mostrato nella figura 2.
Aggiungi un elemento <CustomAttribute>
a ogni elemento ConstraintSet
, come mostrato nel seguente snippet di codice:
<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>
Attributi MotionLayout aggiuntivi
Oltre agli attributi nell'esempio precedente, MotionLayout
ha altri
attributi che potresti voler specificare:
app:applyMotionScene="boolean"
indica se applicare la scena di movimento. Il valore predefinito di questo attributo ètrue
.app:showPaths="boolean"
indica se mostrare i percorsi di movimento durante l'esecuzione del movimento. Il valore predefinito di questo attributo èfalse
.app:progress="float"
consente di specificare in modo esplicito lo stato di avanzamento della transizione. Puoi utilizzare qualsiasi valore in virgola mobile da0
(l'inizio della transizione) a1
(la fine della transizione).app:currentState="reference"
ti consente di specificare unConstraintSet
specifico.app:motionDebug
ti consente di visualizzare ulteriori informazioni di debug sul movimento. I valori possibili sono"SHOW_PROGRESS"
,"SHOW_PATH"
o"SHOW_ALL"
.
Risorse aggiuntive
Per ulteriori informazioni su MotionLayout
, consulta le seguenti risorse:
- Android avanzato in Kotlin 03.2: animazione con MotionLayout
- Esempi di MotionLayout
- Esempi di MotionLayout/ConstraintLayout su GitHub
- Introduzione a MotionLayout (parte I)
- Introduzione a MotionLayout (parte II)
- Introduzione a MotionLayout (parte III)
- Introduzione a MotionLayout (parte IV)