O MotionLayout
é um tipo de layout que ajuda a gerenciar movimento e widget de animação no seu app. O MotionLayout
é uma subclasse do ConstraintLayout
que aproveita os recursos avançados de layout dessa ferramenta. Como parte da biblioteca do ConstraintLayout
, o MotionLayout
está disponível como uma biblioteca de suporte e é compatível com versões anteriores da API de nível 14.

O MotionLayout
preenche a lacuna entre as transições de layout e o processamento complexo de movimentos, oferecendo uma combinação de recursos entre o framework de animação de propriedade, TransitionManager
e CoordinatorLayout
.
Além de descrever transições entre layouts, o MotionLayout
permite que você anime qualquer propriedade de layout também. Além disso, ele é compatível com transições pesquisáveis. Isso significa que você pode mostrar instantaneamente qualquer ponto dentro da transição com base em alguma condição, por exemplo, a entrada por toque. O MotionLayout
também é compatível com frames-chave, permitindo transições totalmente personalizadas para atender às suas necessidades.
O MotionLayout
é totalmente declarativo, o que significa que você pode descrever qualquer transição em XML, independentemente da complexidade.
Considerações sobre design
O MotionLayout
destina-se a mover, redimensionar e animar elementos de IU com que os usuários interagem, como botões e barras de título. O movimento não deve ser simplesmente um efeito especial desnecessário no app. É recomendável que ele seja usado para ajudar os usuários a entender o que o app está fazendo. Para saber mais sobre como projetar seu app com movimento, consulte a seção "Material Design" em Entendendo o movimento.
Primeiros passos
Siga estas etapas para começar a usar o MotionLayout
no seu projeto.
-
Adicione a dependência
ConstraintLayout
: para usarMotionLayout
no seu projeto, adicione a dependênciaConstraintLayout
2.0 ao arquivobuild.gradle
do app. Se você estiver usando o AndroidX, adicione a seguinte dependência:dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta1' }
Se você não estiver usando o AndroidX, adicione a seguinte dependência da Biblioteca de Suporte:
dependencies { implementation 'com.android.support.constraint:constraint-layout:2.0.0-beta1' }
-
Criar um arquivo
MotionLayout
: oMotionLayout
é uma subclasse deConstraintLayout
; portanto, você possa transformar qualquerConstraintLayout
em umMotionLayout
, substituindo o nome da classe no arquivo de recurso de layout, como mostrado nos seguintes exemplos:AndroidX
<!-- before: ConstraintLayout --> <androidx.constraintlayout.widget.ConstraintLayout .../> <!-- after: MotionLayout --> <androidx.constraintlayout.motion.widget.MotionLayout .../>
Biblioteca de Suporte
<!-- before: ConstraintLayout --> <android.support.constraint.ConstraintLayout .../> <!-- after: MotionLayout --> <android.support.constraint.motion.MotionLayout .../>
Veja um exemplo completo de um arquivo
MotionLayout
que pode ser usado para criar o movimento da 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 Suporte
<?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>
-
Criar um MotionScene: no exemplo anterior de
MotionLayout
, o atributoapp:layoutDescription
refere-se a um MotionScene. Um MotionScene é um arquivo de recurso XML que contém todas as descrições de movimento para o layout correspondente. Para manter as informações de layout separadas das descrições de movimento, cadaMotionLayout
faz referência a um único MotionScene. Observe que as definições no MotionScene têm precedência sobre quaisquer definições semelhantes noMotionLayout
.Veja um exemplo de um arquivo MotionScene que descreve o movimento horizontal básico da 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>
Observe o seguinte:
-
<Transition>
contém a definição básica do movimento.-
motion:constraintSetStart
emotion:constraintSetEnd
são referências aos endpoints da animação. Esses endpoints são definidos nos elementos<ConstraintSet>
posteriormente no MotionScene. -
motion:duration
especifica o número de milissegundos necessários para que a animação seja concluída.
-
-
<OnSwipe>
permite controlar o movimento por toque.-
motion:touchAnchorId
refere-se à visualização que você pode deslizar e arrastar. -
motion:touchAnchorSide
significa que estamos arrastando a visualização a partir do lado direito. -
motion:dragDirection
refere-se à direção do avanço da ação de arrastar. Por exemplo,motion:dragDirection="dragRight"
significa que o avanço aumenta conforme você arrasta para a direita.
-
-
<ConstraintSet>
é onde você define as várias restrições que descrevem seu movimento. Neste exemplo, definimos umConstraintSet
para cada endpoint do nosso movimento. Esses endpoints são centralizados verticalmente (viaapp:layout_constraintTop_toTopOf="parent"
eapp:layout_constraintBottom_toBottomOf="parent"
). Horizontalmente, os endpoints estão nas extremidades esquerda e direita da tela.
Para ter uma visão mais detalhada dos diversos elementos compatíveis com o MotionScene, consulte os Exemplos do MotionLayout.
-
Atributos interpolados
Em um arquivo MotionScene, os elementos do ConstraintSet
podem conter atributos adicionais que são interpolados durante a transição. Além da posição e dos limites, os seguintes atributos são interpolados pelo MotionLayout
:
alpha
visibility
elevation
rotation
,rotationX
,rotationY
translationX
,translationY
,translationZ
scaleX
,scaleY
Atributos personalizados
Em um <Constraint>
, você pode usar o elemento <CustomAttribute>
para especificar uma transição para atributos que não são relacionados simplesmente a posição ou atributos View
.
<Constraint android:id="@+id/button" ...> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#D81B60"/> </Constraint>
Um <CustomAttribute>
contém dois atributos próprios:
motion:attributeName
: é obrigatório e deve corresponder a um objeto com métodos getter e setter. O getter e o setter correspondem muito a um padrão específico. Por exemplo,backgroundColor
é compatível, porque nossa visualização tem os métodosgetBackgroundColor()
esetBackgroundColor()
.- O outro atributo que você precisa fornecer é baseado no tipo de valor. Escolha um dos seguintes tipos compatíveis:
motion:customColorValue
para coresmotion:customIntegerValue
para números inteirosmotion:customFloatValue
para flutuantesmotion:customStringValue
para stringsmotion:customDimension
para dimensõesmotion:customBoolean
para booleanos
Observe que, ao especificar um atributo personalizado, você precisa definir valores de endpoint nos elementos inicial e final do <ConstraintSet>
.
Exemplo: alterar a cor do segundo plano
Com base em exemplo anterior, vamos fazer com que a visualização mude as cores como parte do movimento, como mostrado na figura 2.

Adicione um elemento <CustomAttribute>
a cada elemento ConstraintSet
, conforme mostrado abaixo.
<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 adicionais do MotionLayout
Além dos atributos no exemplo acima, o MotionLayout
tem outros atributos que você pode especificar:
app:applyMotionScene="boolean"
: indica se o MotionScene será aplicado. O valor padrão para este atributo étrue
.app:showPaths="boolean"
: indica se os caminhos de movimento serão exibidos conforme o movimento estiver sendo executado. O valor padrão para este atributo éfalse
.app:progress="float"
: permite que você especifique explicitamente o andamento da transição. Você pode usar qualquer pontuação flutuante de0
(o início da transição) a1
(o final da transição).app:currentState="reference"
: permite que você especifique umConstraintSet
.app:motionDebug
: permite exibir informações de depuração adicionais sobre o movimento. Os valores possíveis são SHOW_PROGRESS, SHOW_PATH ou SHOW_ALL.
Outros recursos
Para saber mais sobre o MotionLayout
, consulte os seguintes links: