MotionLayout
è un tipo di layout che ti consente di gestire l'animazione e l'animazione dei widget nella tua app.
MotionLayout
è una sottoclasse di
ConstraintLayout
e si basa sulle sue funzionalità
di layout avanzate. Poiché fa parte della libreria ConstraintLayout
, MotionLayout
è disponibile come libreria di supporto.
MotionLayout
colma il divario tra le transizioni di layout e la gestione dei movimenti complessa,
offrendo un mix di funzionalità tra il framework di animazione
della proprietà,
TransitionManager
e
CoordinatorLayout
.
Oltre a descrivere le transizioni tra i layout, MotionLayout
consente di
animare le proprietà del layout. Inoltre, supporta intrinsecamente le transizioni
in ricerca. Questo significa che puoi mostrare subito qualsiasi punto della transizione
in base ad alcune condizioni, ad esempio l'input tocco. MotionLayout
supporta anche i fotogrammi chiave, consentendo transizioni completamente personalizzate in base alle tue esigenze.
MotionLayout
è un'espressione completamente dichiarativa, il che significa che puoi descrivere qualsiasi transizione in
XML, a prescindere dalla sua complessità.
Considerazioni sulla progettazione
MotionLayout
è progettato per spostare, ridimensionare e animare gli elementi dell'interfaccia utente con cui
interagiscono gli utenti, ad esempio pulsanti e barre dei titoli. Non usare il movimento nella tua app
come effetto speciale senza costi. Usalo per aiutare gli utenti a capire
che cosa sta facendo la tua app. Per ulteriori informazioni sulla progettazione di app con il movimento, consulta la sezione Material Design Comprendere il movimento.
Inizia
Segui questi passaggi per iniziare a utilizzare MotionLayout
nel tuo progetto.
-
Aggiungi la dipendenza
ConstraintLayout
: per utilizzareMotionLayout
nel progetto, aggiungi la dipendenzaConstraintLayout
2.0 al filebuild.gradle
dell'app. Se utilizzi AndroidX, aggiungi la dipendenza seguente:Trendy
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.0-alpha13" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.0-alpha13") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13") }
-
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 nei seguenti esempi: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 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 in movimento: nell'esempio
MotionLayout
precedente, l'attributoapp:layoutDescription
fa riferimento a una scena di movimento. Una scena di movimento è un file di risorse XML. All'interno dell'elemento principale<MotionScene>
, una scena di movimento contiene tutte le descrizioni di movimento per il layout corrispondente. Per mantenere le informazioni di layout separate dalle descrizioni dei movimenti, ogniMotionLayout
fa riferimento a una scena di movimento separata. Le definizioni nella scena di movimento hanno la precedenza su qualsiasi definizione simile inMotionLayout
.Ecco un file di scena di movimento di esempio 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>
ti consente di creare un controllo 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"
significa che l'avanzamento aumenta man mano che la visualizzazione viene trascinata verso destra.
-
-
In
<ConstraintSet>
definisci i vari vincoli che descrivono il tuo 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"
. In orizzontale, i punti finali si trovano ai lati sinistro e destro dello schermo.
Per un'analisi più dettagliata dei vari elementi supportati da una scena di movimento, consulta gli esempi di MotionLayout.
-
Attributi interpolati
All'interno di un file di scena di movimento, gli elementi ConstraintSet
possono contenere attributi aggiuntivi che vengono interpolati durante la transizione. Oltre alla posizione e ai limiti, i seguenti attributi sono interpolati da MotionLayout
:
alpha
visibility
elevation
rotation
,rotationX
erotationY
translationX
,translationY
etranslationZ
scaleX
,scaleY
Attributi personalizzati
All'interno di un elemento <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 elemento <CustomAttribute>
contiene due attributi propri:
motion:attributeName
è obbligatorio e deve corrispondere a un oggetto con i metodi getter e setter. getter e setter devono corrispondere a un pattern specifico. Ad esempio,backgroundColor
è supportato, poiché la vista ha metodigetBackgroundColor()
esetBackgroundColor()
sottostanti.- L'altro attributo che devi fornire si basa sul tipo di valore. Scegli tra i seguenti tipi supportati:
motion:customColorValue
per i colorimotion:customIntegerValue
per i numeri interimotion:customFloatValue
per i dati in virgola mobilemotion:customStringValue
per stringhemotion:customDimension
per le dimensionimotion:customBoolean
per i valori booleani
Quando specifichi un attributo personalizzato, definisci i valori dell'endpoint in entrambi gli elementi <ConstraintSet>
di inizio e di fine.
Cambia il colore dello sfondo
Partendo dall'esempio precedente, supponi di voler modificare i colori della vista durante il 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 visualizzare i percorsi di animazione mentre l'animazione è in esecuzione. Il valore predefinito di questo attributo èfalse
.app:progress="float"
ti consente di specificare esplicitamente l'avanzamento della transizione. Puoi utilizzare qualsiasi valore con virgola mobile da0
(l'inizio della transizione) a1
(la fine della transizione).app:currentState="reference"
consente di specificare un valoreConstraintSet
specifico.app:motionDebug
consente di visualizzare ulteriori informazioni di debug sul movimento. I valori possibili sono"SHOW_PROGRESS"
,"SHOW_PATH"
o"SHOW_ALL"
.
Risorse aggiuntive
Per maggiori informazioni su MotionLayout
, consulta le seguenti risorse:
- Android avanzato in Kotlin 03.2: animazione con MotionLayout
- Esempi di MotionLayout
- MotionLayout/ConstraintLayout Samples su GitHub
- Introduzione a MotionLayout (parte I)
- Introduzione a MotionLayout (parte II)
- Introduzione a MotionLayout (parte III)
- Introduzione a MotionLayout (parte IV)