MotionLayout
es un tipo de diseño que te ayuda a administrar las animaciones de movimiento y widgets en tu app. MotionLayout
es una subclase de ConstraintLayout
y se basa en sus capacidades de diseño enriquecido. Como parte de la biblioteca de ConstraintLayout
, MotionLayout
está disponible como una biblioteca de compatibilidad y es compatible con versiones anteriores a la API nivel 14.

MotionLayout
reduce las diferencias entre las transiciones de diseño y el manejo de movimiento complejo, lo que ofrece una combinación de características entre el marco de animación de propiedades , TransitionManager
y CoordinatorLayout
.
Además de describir las transiciones entre diseños, MotionLayout
también te permite animar cualquier propiedad de diseño. Además, es inherentemente compatible con las transiciones que admiten búsquedas. Esto significa que puedes mostrar de forma instantánea cualquier punto dentro de la transición en función de alguna condición, como la entrada táctil. MotionLayout
también admite fotogramas clave, lo que habilita el uso de transiciones totalmente personalizadas para satisfacer tus necesidades.
MotionLayout
es totalmente declarativo, lo que significa que puedes describir cualquier transición en XML, independientemente de su complejidad.
Consideraciones del diseño
MotionLayout
está diseñado para mover, cambiar el tamaño y animar los elementos de la IU con los que interactúan los usuarios, como botones y barras de títulos. En tu app, el movimiento no debe ser simplemente un efecto especial injustificado. Se debe usar para ayudar a los usuarios a comprender lo que hace tu app. Para obtener más información sobre cómo diseñar una app con movimiento, consulta la sección Material Design en Información sobre el movimiento.
Comenzar
Sigue estos pasos para comenzar a usar MotionLayout
en tu proyecto.
-
Incluye la dependencia
ConstraintLayout
: para usarMotionLayout
en tu proyecto, agrega la dependenciaConstraintLayout
2.0 al archivobuild.gradle
de tu app. Si usas AndroidX, agrega la siguiente dependencia:dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta1' }
Si no usas AndroidX, agrega la siguiente dependencia de la biblioteca de compatibilidad:
dependencies { implementation 'com.android.support.constraint:constraint-layout:2.0.0-beta1' }
-
Crea un archivo
MotionLayout
:MotionLayout
es una subclase deConstraintLayout
, de modo que puedes transformar cualquierConstraintLayout
existente en unMotionLayout
si reemplazas el nombre de la clase en tu archivo de recursos de diseño, como se muestra en los siguientes ejemplos:AndroidX
<!-- before: ConstraintLayout --> <androidx.constraintlayout.widget.ConstraintLayout .../> <!-- after: MotionLayout --> <androidx.constraintlayout.motion.widget.MotionLayout .../>
Biblioteca de compatibilidad
<!-- before: ConstraintLayout --> <android.support.constraint.ConstraintLayout .../> <!-- after: MotionLayout --> <android.support.constraint.motion.MotionLayout .../>
Este es un ejemplo completo de un archivo
MotionLayout
que puedes usar para crear el movimiento en la 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>
Biblioteca de compatibilidad
<?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 un archivo MotionScene: en el ejemplo de
MotionLayout
anterior, el atributoapp:layoutDescription
hace referencia a un MotionScene. MotionScene es un archivo XML de recursos que contiene todas las descripciones de movimientos para el diseño correspondiente. A fin de mantener la información de diseño separada de las descripciones de movimientos, cadaMotionLayout
hace referencia a un archivo MotionScene separado. Ten en cuenta que las definiciones de MotionScene tienen prioridad sobre cualquier definición similar deMotionLayout
.El siguiente es un ejemplo de archivo MotionScene en el que se describe el movimiento horizontal básico en la 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>
Ten en cuenta lo siguiente:
-
<Transition>
contiene la definición básica del movimiento.-
motion:constraintSetStart
ymotion:constraintSetEnd
son referencias a los extremos del movimiento. Se incluye la definición de estos extremos en los elementos<ConstraintSet>
más adelante, en el archivo MotionScene. -
motion:duration
especifica la cantidad de milisegundos que tarda en completarse el movimiento.
-
-
<OnSwipe>
te permite controlar el movimiento a través del tacto.-
motion:touchAnchorId
hace referencia a la vista que puedes deslizar y arrastrar. -
motion:touchAnchorSide
indica que se arrastra la vista desde el lado derecho. -
motion:dragDirection
hace referencia a la dirección de progreso del arrastre. Por ejemplo,motion:dragDirection="dragRight"
indica que el progreso aumenta a medida que arrastras hacia la derecha.
-
-
<ConstraintSet>
es donde debes definir las diversas restricciones que describen tu movimiento. En este ejemplo, definimos unConstraintSet
para cada extremo de nuestro movimiento. Estos extremos están centrados verticalmente (a través deapp:layout_constraintTop_toTopOf="parent"
yapp:layout_constraintBottom_toBottomOf="parent"
). De manera horizontal, los extremos están en los límites izquierdo y derecho de la pantalla.
Para obtener una vista más detallada de los diversos elementos compatibles con MotionScene, consulta los ejemplos de MotionLayout.
-
Atributos interpolados
Dentro de un archivo MotionScene, los elementos ConstraintSet
pueden contener atributos adicionales que se interpolan durante la transición. Además de la posición y los límites, MotionLayout
interpola los siguientes atributos:
alpha
visibility
elevation
rotation
,rotationX
,rotationY
translationX
,translationY
,translationZ
scaleX
,scaleY
Atributos personalizados
Dentro de un <Constraint>
, puedes usar el elemento <CustomAttribute>
para especificar una transición para los atributos que no están simplemente relacionados con la posición o los atributos View
.
<Constraint android:id="@+id/button" ...> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#D81B60"/> </Constraint>
Un <CustomAttribute>
contiene dos atributos propios:
motion:attributeName
es obligatorio y debe coincidir con un objeto que tenga métodos get y set. Estos deben coincidir con un patrón específico. Por ejemplo,backgroundColor
es compatible, ya que nuestra vista tiene métodosgetBackgroundColor()
ysetBackgroundColor()
subyacentes.- El otro atributo que debes proporcionar se basa en el tipo de valor. Elige entre los siguientes tipos admitidos:
motion:customColorValue
para los coloresmotion:customIntegerValue
para números enterosmotion:customFloatValue
para valores flotantesmotion:customStringValue
para stringsmotion:customDimension
para dimensionesmotion:customBoolean
para valores booleanos
Ten en cuenta que cuando especificas un atributo personalizado, debes definir valores de extremo en los elementos <ConstraintSet>
de inicio y de finalización.
Ejemplo: Cambiar el color de fondo
Basándonos en nuestro ejemplo anterior, hagamos que la vista cambie de color mientras se mueve, como se muestra en la figura 2.

Agrega un elemento <CustomAttribute>
a cada elemento ConstraintSet
, como se muestra a continuación:
<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>
Atributos adicionales de MotionLayout
Además de los atributos que se muestran en el ejemplo anterior, MotionLayout
tiene otros atributos que conviene especificar:
app:applyMotionScene="boolean"
indica si se debe aplicar el archivo MotionScene. El valor predeterminado para este atributo estrue
.app:showPaths="boolean"
indica si se muestran las rutas de movimiento mientras se ejecuta el movimiento. El valor predeterminado para este atributo esfalse
.app:progress="float"
te permite especificar explícitamente el progreso de la transición. Puedes usar cualquier valor de punto flotante desde0
(el inicio de la transición) hasta1
(el final de la transición).app:currentState="reference"
te permite especificar unConstraintSet
específico.app:motionDebug
te permite mostrar información adicional de depuración sobre el movimiento. Los valores posibles son "SHOW_PROGRESS", "SHOW_PATH" o "SHOW_ALL".
Recursos adicionales
Para obtener más información sobre MotionLayout
, consulta los siguientes vínculos: