MotionLayout
é um tipo de layout que ajuda a gerenciar o movimento e a animação de widgets no seu app.
MotionLayout
é uma subclasse de
ConstraintLayout
e com base nos recursos
recursos de layout. Como parte da biblioteca ConstraintLayout
, MotionLayout
está disponível como uma biblioteca de suporte.
O MotionLayout
preenche a lacuna entre as transições de layout e os movimentos complexos
, oferecendo uma mistura de recursos entre a animação de propriedade
framework,
TransitionManager
e
CoordinatorLayout
.
Além de descrever transições entre layouts, o MotionLayout
permite que você
animar qualquer propriedade de layout. Além disso, ele oferece inerentemente o suporte acessível
transições. Isso significa que é possível mostrar instantaneamente qualquer ponto da transição
com base em alguma condição, como a entrada por toque. MotionLayout
também oferece suporte
frames-chave, permitindo transições totalmente personalizadas para atender às suas necessidades.
MotionLayout
é totalmente declarativo, ou seja, é possível descrever qualquer transição
XML, não importa a complexidade.
Considerações sobre o design
MotionLayout
destina-se a mover, redimensionar e animar elementos de interface com os quais
com que os usuários interagem, como botões e barras de título. Não use o movimento no seu app como
um efeito especial desnecessário. Use esse recurso para ajudar os usuários a entender o que é seu app
fazendo. Para mais informações sobre como projetar seu app com movimento, consulte a
Seção Noções básicas sobre o Material Design
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 o dependência doConstraintLayout
2.0 para abuild.gradle
. Se estiver usando o AndroidX, adicione o seguinte dependência:Groovy
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.0-alpha14" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha14" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.0-alpha14") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha14") }
-
Crie um arquivo
MotionLayout
:MotionLayout
como uma subclasse deConstraintLayout
, é possível transformar osConstraintLayout
existentes em umMotionLayout
ao substituindo o nome da classe no arquivo de recurso de layout, conforme mostrado no exemplos a seguir: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 .../>
Aqui está um exemplo completo de um arquivo
MotionLayout
, que define o layout mostrado na 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>
-
Crie um MotionScene: no
MotionLayout
anterior. exemplo, o atributoapp:layoutDescription
faz referência a uma cena em movimento. Uma cena em movimento é um arquivo de recurso XML. Dentro de<MotionScene>
elemento raiz, uma cena contém todas as descrições do movimento pelo layout correspondente. Para manter as informações de layout separadas do movimento descrições, cadaMotionLayout
faz referência a um movimento diferente cena As definições na cena com movimento têm precedência sobre qualquer outra definições naMotionLayout
.Veja um exemplo de arquivo de cena em movimento que descreve a visão horizontal básica movimento na 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 ao pontos finais do movimento. Esses endpoints são definidos<ConstraintSet>
elementos mais tarde na cena em movimento. -
motion:duration
especifica o número de milissegundos. para que o movimento seja concluído.
-
-
<OnSwipe>
permite criar um controle por toque para o movimento.-
motion:touchAnchorId
se refere à visualização que o usuário pode deslizar e arrastar. -
motion:touchAnchorSide
significa está sendo arrastada do lado direito. -
motion:dragDirection
refere-se ao progresso direção do arrasto. Por exemplo:motion:dragDirection="dragRight"
significa progresso aumenta à medida que a visualização é arrastada para a direita.
-
-
<ConstraintSet>
é onde você define as várias restrições que descrevem seu movimento. Neste exemplo, um<ConstraintSet>
é definido para cada ponto final do seu movimento. Esses endpoints são centralizados verticalmente usandoapp:layout_constraintTop_toTopOf="parent"
eapp:layout_constraintBottom_toBottomOf="parent"
. Horizontalmente, os endpoints estão nos lados esquerdo e direito do tela.
Para uma visão mais detalhada dos vários elementos que uma cena em movimento suporta, consulte a Exemplos do MotionLayout.
-
Atributos interpolados
Dentro de um arquivo de cena em movimento, os elementos ConstraintSet
podem conter
atributos interpolados durante a transição. Além da posição e
limites, os seguintes atributos são interpolados por 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 simplesmente relacionados à posição ou View
atributos.
<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 getter e setter. O getter e o setter precisam corresponder a um padrão específico. Para exemplo, há suporte parabackgroundColor
, já que a visualização temgetBackgroundColor()
esetBackgroundColor()
.- O outro atributo que você precisa fornecer é baseado no tipo de valor. Escolha entre
os 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
Ao especificar um atributo personalizado, defina valores de ponto de extremidade no início e
elementos <ConstraintSet>
finais.
Mudar cor do plano de fundo
Com base no exemplo anterior, suponha que você queira que as cores da visualização mudem como parte do movimento, como mostrado na figura 2.
Adicione um elemento <CustomAttribute>
a cada elemento ConstraintSet
, conforme mostrado em
o seguinte snippet de código:
<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 anterior, MotionLayout
tem outros
atributos que convém especificar:
app:applyMotionScene="boolean"
indica se a cena em movimento será aplicada. O valor padrão para este atributo étrue
.app:showPaths="boolean"
indica se as demarcações de animação serão mostradas como movimento está correndo. 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 valor de ponto flutuante de0
(o início da transição) até1
. (o fim da transição).app:currentState="reference"
: permite que você especifique umConstraintSet
.app:motionDebug
permite exibir mais informações de depuração sobre o movimento. Os valores possíveis são"SHOW_PROGRESS"
,"SHOW_PATH"
ou"SHOW_ALL"
.
Outros recursos
Para mais informações sobre MotionLayout
, consulte os seguintes recursos:
- Android avançado no Kotlin 03.2: animação com o MotionLayout
- Exemplos do MotionLayout
- Exemplos de MotionLayout/ConstraintLayout no GitHub (link em inglês)
- Introdução ao MotionLayout (parte I)
- Introdução ao MotionLayout (parte II)
- Introdução ao MotionLayout (parte III)
- Introdução ao MotionLayout (parte IV) (em inglês)