This tutorial will walk you through creating your first MotionLayout steps.
Using MotionLayout, you'll learn the following concepts:
Hope you'll enjoy the codelab!
The source code for this codelab can be found on Github.
In this step, you will download the code for the entire codelab and run a simple example app.
Click the following link to download the source code for this codelab:
Download Code Lab sources

The app will display a crazy Emoji and two bottons. You should see something like this:

Feel free to visit us on GitHub.
The first phase is on the master branch.
The most important thing to understand in MotionLayout is its structure.
Positioning views in MotionLayout is divided into two scenarios:
ConstraintLayout toolset - as MotionLayout is a subclass of it.MotionLayout, without positioning attributes. Positioning them will be done by an external XML file, called Scene.When you want to animate a view in your MotionLayout, you will delegate its constraints to your scene file.
A scene is basically where you describe the occurrences of your animations.
Each scene is composed of:
The system will calculate all of these parameters and handle the animation for you.
To summarize:
The first thing you'll want to do is to note where is the scene XML.
You'll do that by adding the layoutDescription parameter to the root view, which just points to the file where the animations are being described.
activity_main.xml, and add the following line into your MotionLayout root view : app:layoutDescription="@xml/scene_01"
Your view should look as follows:
<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_container"
android:background="#ffffff"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/scene_01"
tools:context=".MainActivity">
Next, create a filed called scene_01.xml.
xml under res:
scene_01.xml - inside res -> xml.<?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:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:duration="1000">
</Transition>
<ConstraintSet android:id="@+id/start">
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
</ConstraintSet>
</MotionScene>
Explanation:
In order to take control of an animation, you need to define a MotionScene.
MotionScene is the entity describing the animation. in your case, you'll make a transition from point A to point B on the screen, with a duration of 1 second.
Every point is a ConstraintSet.
The animation will start at @+id/start, and end at @+id/end.
@+id/start:<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent"/>
@+id/end:<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent"/>
Your scene_01.xml file should look like this:
<?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:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:duration="1000">
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
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/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent"/>
</ConstraintSet>
</MotionScene>
Explanation:
Take a look at the <Constraint> of the @+id/start ConstraintSet,
@+id/main_iv).The constraints in @+id/end are the same, with the only difference being the view is attached to the right.
MainActivity.java.animateToEndButton's onClick call back:mMotionLayout.transitionToEnd();
animateToStartButton's onClick call back:mMotionLayout.transitionToStart();
Your onClick listeners should look like this:
animateToEndButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mMotionLayout.transitionToEnd();
}
});
animateToStartButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mMotionLayout.transitionToStart();
}
});
Run your app
Run the app and tap the buttons - the views should animate back and forth, as expected.
Click the following button to download the source code for this chapter:
Download Code Lab sources

The app should look like this:

Pay attention to the following changes:
View instead of an ImageView in MainActivity.xml. <View
android:id="@+id/main_iv"
android:layout_width="64dp"
android:layout_height="64dp"
android:background="@color/colorAccent"
/>
scene_02.xml.@xml/scene_02 :app:layoutDescription="@xml/scene_02"
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/main_iv"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginBottom="8dp"
motion:layout_constraintBottom_toTopOf="@+id/animate_to_start_bt"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintEnd_toEndOf="parent"/>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/main_iv"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginTop="8dp"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent"/>
</ConstraintSet>
Give it a shot by playing with the buttons.
Let's go over some attributes that can be changed during the animation.
ConstraintSet to 164dpandroid:layout_height="164dp"
Run your app
Constraintandroid:alpha="1.0"
Add the following attribute to your end Constraint
android:alpha="0.5"
Run your app
Constraintandroid:rotation="0.0"
Add the following attribute to your end Constraint
android:rotation="-720"
Run your app
Constraintandroid:translationX="0dp"
Add the following attribute to your end Constraint
android:translationX="100dp"
Run your app
CustomAttribute to your Constraint, both the start and the end:<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/main_iv"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginBottom="8dp"
motion:layout_constraintBottom_toTopOf="@+id/animate_to_start_bt"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent">
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="#00ff00" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/main_iv"
android:layout_width="64dp"
android:layout_height="164dp"
android:layout_marginTop="8dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="#ff0000" />
</Constraint>
</ConstraintSet>
Run your app
A quick word about interpolations.
You can define an interpolator for every <Transition>.

Images have a special set of attributes you're going to try and explore.
Go back to your image view settings :
drawable folder.ImageFilterView instead of a View in MainActivity.xml. <android.support.constraint.utils.ImageFilterView
android:id="@+id/main_iv"
android:src="@drawable/icon2"
android:layout_width="64dp"
android:layout_height="64dp"/>
scene_03.xml.@xml/scene_03 :app:layoutDescription="@xml/scene_03"
scene_03.xml.<?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:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:duration="1000">
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent">
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent">
</Constraint>
</ConstraintSet>
</MotionScene>
You can also checkout the image_manipulation branch.
scene_03.xml, add a saturation CustomAttribute to the start and end Constraints :<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="saturation"
motion:customFloatValue="1" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="saturation"
motion:customFloatValue="0" />
</Constraint>
</ConstraintSet>
Run your appscene_03.xml, add a contrast CustomAttribute to the start Constraint :<CustomAttribute
motion:attributeName="contrast"
motion:customFloatValue="1" />
And your end Constraint should get:<CustomAttribute
motion:attributeName="contrast"
motion:customFloatValue="1" />
Run your appscene_03.xml, add a warmth CustomAttribute to the start Constraint :<CustomAttribute
motion:attributeName="warmth"
motion:customFloatValue="1" />
And your end Constraint should get :<CustomAttribute
motion:attributeName="warmth"
motion:customFloatValue="2" />
Run your appactivity_main.xml, Add altSrc to your ImageFilterView :<android.support.constraint.utils.ImageFilterView
android:id="@+id/main_iv"
android:src="@drawable/icon2"
app:altSrc="@drawable/icon"
android:layout_width="64dp"
android:layout_height="64dp"/>
scene_03.xml, add a crossfade CustomAttribute to the start and the end Constraint :<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="crossfade"
motion:customFloatValue="0" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="crossfade"
motion:customFloatValue="1" />
</Constraint>
</ConstraintSet>
Run your appMotionLayout can handle the transition without any callbacks in your code. You can add interactivity by specifying relevant options in your XML scene.
Your user will be able to simply swipe the views back and forth to animate them.
This swipe isn't a simple trigger, but also takes acceleration and velocity into account.
Let's try it now.
activity_main.xml and remove handleViews() from MainActivity.java.app:layoutDescription="@xml/scene_04"
scene_04.xml.<?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:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:duration="1000">
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent">
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent">
</Constraint>
</ConstraintSet>
</MotionScene>
activity_main.xml should look like:<?xml version="1.0" encoding="utf-8"?>
<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_container"
android:background="#ffffff"
android:layout_width="match_parent"
app:layoutDescription="@xml/scene_04"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.constraint.utils.ImageFilterView
android:id="@+id/main_iv"
android:src="@drawable/icon2"
android:layout_width="64dp"
android:layout_height="64dp"/>
</android.support.constraint.motion.MotionLayout>
scene_04.xml, and change your <Transition> into the following :<Transition
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:duration="1000">
<OnSwipe
motion:touchAnchorId="@+id/main_iv"
motion:touchAnchorSide="right"
motion:dragDirection="dragRight" />
</Transition>
Run your app
Up until now, you defined a pair of start and end states, letting MotionLayout transition between them.
You might ask your self, though - what if I want more than two states?
This is where Keyframes are powerful.
The main idea of a Keyframes is to give you a way to manipulate the animation in terms of size, color, rotation etc during its transition from the start to end state.
Next, you'll take an ImageView from bottom to top (centered horizontally), but this time ading a Keyframe that changes the bottom-up linear path into a diagonal path that goes from bottom-end to center-start and then to up-end.
scene_05.xml.layoutDescription reference to point to @xml/scene_05 :app:layoutDescription="@xml/scene_05"
scene_05.xml.<?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:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:duration="1000">
<OnSwipe
motion:touchAnchorId="@+id/main_iv"
motion:touchAnchorSide="top"
motion:dragDirection="dragUp"/>
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginBottom="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintEnd_toEndOf="parent">
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginTop="8dp"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent">
</Constraint>
</ConstraintSet>
</MotionScene>
onSwipe:<KeyFrameSet>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentX="0"
motion:framePosition="50"
motion:target="@id/main_iv"/>
</KeyFrameSet>
Run your app
Explanation :
percentX: Left of the parent.framePosition: When the action takes place in the timeline.target: The view being affected by the transition.Let's try a more complicated KeyFrameSet.
KeyFrameSet with the following :<KeyFrameSet>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentX="0"
motion:framePosition="25"
motion:target="@id/main_iv"/>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentX="1"
motion:framePosition="50"
motion:target="@id/main_iv"/>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentX="0"
motion:framePosition="70"
motion:target="@id/main_iv"/>
</KeyFrameSet>
Run your app
Let's step it up a notch! Aside from KeyFrames, you also have KeyAttribute which lets you play around with basic view attributes such as size, color, rotation etc.
Enlarge your view to twice its size and rotate it -45 degrees at the halfway point of your animation:
KeyFrameSet with the following :<KeyFrameSet>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentX="0"
motion:framePosition="25"
motion:target="@id/main_iv"/>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentX="1"
motion:framePosition="50"
motion:target="@id/main_iv"/>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentX="0"
motion:framePosition="70"
motion:target="@id/main_iv"/>
<KeyAttribute
android:scaleX="2"
android:scaleY="2"
android:rotation="-45"
motion:framePosition="50"
motion:target="@id/main_iv" />
</KeyFrameSet>
Run your app
And if we will go wild :
KeyFrameSet with the following :<KeyFrameSet>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentX="0"
motion:framePosition="25"
motion:target="@id/main_iv"/>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentX="1"
motion:framePosition="50"
motion:target="@id/main_iv"/>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentX="0"
motion:framePosition="70"
motion:target="@id/main_iv"/>
<KeyAttribute
android:rotation="-45"
motion:framePosition="25"
motion:target="@id/main_iv" />
<KeyAttribute
android:scaleX="2"
android:scaleY="2"
android:rotation="-245"
motion:framePosition="50"
motion:target="@id/main_iv" />
<KeyAttribute
android:rotation="-445"
motion:framePosition="75"
motion:target="@id/main_iv" />
</KeyFrameSet>
Run your app
You can leverage keyframes to create some cool combinations.
scene_06.xml.layoutDescription reference to point to @xml/scene_06 :app:layoutDescription="@xml/scene_06"
scene_06.xml:<?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:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:duration="1000">
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginBottom="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent">
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginTop="8dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent">
</Constraint>
</ConstraintSet>
</MotionScene>
activity_main.xml and add the following lines:<Button
android:id="@+id/animate_to_start_bt"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginBottom="10dp"
android:text="Animate To Start"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/animate_to_End_bt"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"/>
<Button
android:id="@+id/animate_to_End_bt"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginBottom="10dp"
android:text="Animate To End"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/animate_to_start_bt"/>
Also, in activity_main.xml, add :
private void handleViews() {
animateToEndButton = findViewById(R.id.animate_to_End_bt);
animateToStartButton = findViewById(R.id.animate_to_start_bt);
mMotionLayout = findViewById(R.id.motionLayout_container);
animateToEndButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mMotionLayout.transitionToEnd();
}
});
animateToStartButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mMotionLayout.transitionToStart();
}
});
}
And call handleViews() from onCreate().
<Transition> :<KeyFrameSet>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentY="0.25"
motion:percentX="0.75"
motion:framePosition="25"
motion:target="@id/main_iv"/>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentY="0.5"
motion:percentX="0.1"
motion:framePosition="50"
motion:target="@id/main_iv"/>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentY="0.75"
motion:percentX="0.75"
motion:framePosition="75"
motion:target="@id/main_iv"/>
</KeyFrameSet>
You can even go a bit crazier and do the following:
<Transition
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:duration="4000">
<KeyFrameSet>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentY="0.80"
motion:percentX="0.80"
motion:framePosition="2"
motion:target="@id/main_iv"/>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentY="0.60"
motion:percentX="0.80"
motion:framePosition="10"
motion:target="@id/main_iv"/>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentY="0.70"
motion:percentX="1"
motion:framePosition="15"
motion:target="@id/main_iv"/>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentY="0.80"
motion:percentX="0.80"
motion:framePosition="20"
motion:target="@id/main_iv"/>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentY="0.80"
motion:percentX="0.20"
motion:framePosition="25"
motion:target="@id/main_iv"/>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentY="0.90"
motion:percentX="0.10"
motion:framePosition="30"
motion:target="@id/main_iv"/>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentY="1"
motion:percentX="0.20"
motion:framePosition="35"
motion:target="@id/main_iv"/>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentY="0.2"
motion:percentX="0.20"
motion:framePosition="40"
motion:target="@id/main_iv"/>
</KeyFrameSet>
</Transition>
Run your app
MotionLayout offers you the ability to transform a linear path between two points to an arch.

scene_07.xml.layoutDescription reference to point to @xml/scene_07:app:layoutDescription="@xml/scene_07"
scene_07.xml.<?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:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start"
motion:duration="1000">
<OnSwipe
motion:touchAnchorId="@+id/main_iv"
motion:touchAnchorSide="top"
motion:dragDirection="dragUp"/>
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginBottom="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent">
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginTop="8dp"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent">
</Constraint>
</ConstraintSet>
</MotionScene>
For this property, you'll want to actually see the path.
activity_main.xml and add the following line to the root view :app:showPaths="true"
scene_06.xml and add to the following line to the child <Constraint> of <ConstraintSet android:id="@+id/start"> :motion:pathMotionArc="startHorizontal"
You should end up with the following:
<ConstraintSet android:id="@+id/start">
<Constraint
motion:pathMotionArc="startHorizontal"
android:id="@+id/main_iv"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginBottom="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent">
</Constraint>
</ConstraintSet>
Run your app
You can also decide that you want your arch to only run for a portion of the path, and not all of it:
<Constraint>:motion:layout_constraintStart_toStartOf="parent"
<Transition> :<KeyFrameSet>
<KeyPosition
motion:keyPositionType="parentRelative"
motion:percentY="0.5"
motion:pathMotionArc="none"
motion:framePosition="50"
motion:target="@id/main_iv"/>
</KeyFrameSet>
Run your app
pathMotionArc to flip :motion:pathMotionArc="flip"
Run your app
The last feature you'll play with today is a tool that lets you monitor your animation manually.
You'll pass the control of the animation to a Seekbar. This way, you can understand exactly what is happening in every frame of your scene, in an interactive way.

You can control the progress of a MotionLayout by the setProgress() method.
activity_main.xml, and add a seekbar instead :<android.support.v7.widget.AppCompatSeekBar
android:id="@+id/seek"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="10dp"/>
MainActivity.java, change handleViews() method to : private void handleViews() {
mMotionLayout = findViewById(R.id.motionLayout_container);
SeekBar seekBar = findViewById(R.id.seek);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
mMotionLayout.setProgress(i / 100f);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
Run your app
Now is your turn :)
You are going to build the following animation:
