Due to its exceptional versatility, the
ConstraintLayout widget has change into the “Swiss Military knife” of layouts for Android app builders. Nonetheless, including complicated animations to its contents, though doable, will be fairly time-consuming. That is why Google launched the
MotionLayout widget in I/O 2018.
MotionLayout widget, which is now part of Android’s assist library, extends the
ConstraintLayout widget. It’s a distinctive widget that means that you can animate its contents declaratively utilizing simply XML. Moreover, it presents fine-grained management over all its animations.
On this tutorial, I am going to present you learn how to add it to your Android Studio initiatives and create just a few totally different animations with it.
To comply with this tutorial, you will want:
- Android Studio three.1.three or greater
- a tool or emulator working Android API degree 21 or greater
- a fundamental understanding of the
1. Add Dependencies
To have the ability to use the
MotionLayout widget in your Android Studio venture, you could have the most recent model of the Constraint Format assist library as an
implementation dependency. Moreover, as a way to keep away from model conflicts, be sure to embody a dependency for the most recent secure model of the v7 appcompat assist library.
Accordingly, add the next code to the
app module’s construct.gradle file:
implementation 'com.android.assist:appcompat-v7:27.Zero.2' implementation 'com.android.assist.constraint:constraint-layout:2.Zero.Zero-alpha1'
2. Outline a Format
MotionLayout widget can do all the things the
ConstraintLayout widget can. Due to this fact, you’ll be able to freely exchange any occasion of the latter with the previous. For now, nonetheless, I counsel you create a brand new format XML file and add the
MotionLayout widget to it as the foundation aspect.
<?xml model="1.Zero" encoding="utf-Eight"?> <android.assist.constraint.movement.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/motion_container"> <!-- Extra code right here --> </android.assist.constraint.movement.MotionLayout>
All through this tutorial, we’ll be animating an
ImageView widget. So add it as the primary little one of the format.
<ImageView android:id="@+id/actor" app:srcCompat="@shade/colorAccent" android:layout_width="wrap_content" android:layout_height="wrap_content" />
You are free to make use of any drawable because the supply of the
ImageView widget. Within the above code, I am utilizing a shade drawable.
Subsequent, add a button you’ll be able to press to begin the animations. The next code exhibits you learn how to place it within the middle of the format:
<Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textual content="Press Me" app:layout_constraintBottom_toBottomOf="mum or dad" app:layout_constraintEnd_toEndOf="mum or dad" app:layout_constraintStart_toStartOf="mum or dad" app:layout_constraintTop_toTopOf="mum or dad" android:onClick="begin"/>
Moreover, to observe the progress of the animations, add a
SeekBar widget to the format and place it under the button. Here is how:
<SeekBar android:layout_width="100dp" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@+id/button" app:layout_constraintEnd_toEndOf="mum or dad" app:layout_constraintStart_toStartOf="mum or dad" android:layout_marginTop="10dp" android:id="@+id/seekbar"/>
Lastly, as a result of there’s an on-click occasion handler related to the button, be sure to outline it in your exercise.
enjoyable begin(v: View)
three. Create a Movement Scene
You’ll have observed that we didn’t add any constraints to the
ImageView widget whereas defining the format. That is as a result of we’ll be including them to a movement scene as a substitute. A movement scene is an XML file that incorporates particulars concerning the animation you need to create with a
To create a brand new movement scene, create an XML useful resource file and add a
MotionScene aspect to it.
<?xml model="1.Zero" encoding="utf-Eight"?> <MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <!-- Extra code right here --> </MotionScene>
A movement scene incorporates
ConstraintSet parts specifying the constraints that should be utilized to a widget at totally different factors within the animation. Movement scene information normally include two constraint units: one for the start of the animation and one for the tip.
The next code exhibits you learn how to create two constraint units that can assist the
MotionLayout widget transfer the
ImageView widget from the underside proper nook of the display screen to the highest left nook:
<ConstraintSet android:id="@+id/starting_set"> <Constraint android:id="@+id/actor" app:layout_constraintBottom_toBottomOf="mum or dad" app:layout_constraintRight_toRightOf="mum or dad" android:layout_width="60dp" android:layout_height="60dp" /> </ConstraintSet> <ConstraintSet android:id="@+id/ending_set"> <Constraint android:id="@+id/actor" app:layout_constraintTop_toTopOf="mum or dad" app:layout_constraintLeft_toLeftOf="mum or dad" android:layout_width="60dp" android:layout_height="60dp" /> </ConstraintSet>
Be aware that every
ConstraintSet aspect should at all times specify each the specified place and the specified measurement. That is essential as a result of it can overwrite any beforehand set format data.
To assist the
MotionLayout widget perceive the order through which the constraint units should be utilized, you could subsequent create a
Transition aspect. Through the use of its intuitively named
constraintSetEnd attributes, you’ll be able to specify which set should be utilized first and which final. The
Transition aspect additionally means that you can specify the period of the animation.
<Transition android:id="@+id/my_transition" app:constraintSetStart="@+id/starting_set" app:constraintSetEnd="@+id/ending_set" app:period="2000"> </Transition>
At this level, the movement scene is full. Nonetheless, the
MotionLayout widget continues to be not conscious of it. So return to the format XML file, add a
layoutDescription attribute to the widget, and set its worth to the identify of the movement scene file.
If the identify of your movement scene file is my_scene.xml, your
MotionLayout widget ought to now appear to be this:
<android.assist.constraint.movement.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:instruments="http://schemas.android.com/instruments" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/my_scene" android:id="@+id/motion_container"> ... </android.assist.constraint.movement.MotionLayout>
four. Begin the Animation
If you run the app, the
MotionLayout widget will robotically apply the constraint set specified within the
constraintSetStart attribute of the
Transition aspect. Due to this fact, to begin the animation, all it’s good to do is name the
transitionToEnd() methodology of the widget. The next code, which should be added to the on-click occasion handler you created in an earlier step, exhibits you the way:
At this level, in the event you run the app and press the button, you must be capable to see the
ImageView widget easily transfer throughout the display screen.
5. Deal with Animation Occasions
By attaching a
TransitionListener object to the
MotionLayout widget, you’ll be able to carefully monitor the progress of the animation.
motion_container.setTransitionListener( object: MotionLayout.TransitionListener )
TransitionListener interface has two summary strategies, and Android Studio will robotically generate stubs for them.
onTransitionCompleted() methodology known as when a transition from one constraint set to a different is full. For now, let’s use it to reset the constraints of the
ImageView widget by calling the
transitionToStart() methodology inside it.
override enjoyable onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int)
onTransitionChange() methodology known as each time the progress of the animation adjustments. As such, the progress is a floating-point quantity that lies between zero and one. The next code exhibits you learn how to replace the
SeekBar primarily based on the progress of the animation:
override enjoyable onTransitionChange(motionLayout: MotionLayout?, startId: Int, endId: Int, progress: Float)
Go forward and run the app once more to see two animations now.
6. Create Key Frames
In our animation, the
ImageView widget strikes in a path that appears like a straight line. That is as a result of the
MotionLayout widget is given solely two factors to work with: the start line, which is on the backside proper nook of the display screen, and the ending level, which is on the prime left nook of the display screen. If you wish to alter the form of the trail, you will have to offer just a few intermediate factors, which lie between the beginning and ending factors. To take action, you will must create new key frames.
Earlier than you begin creating key frames although, you could add a
KeyFrameSet aspect to the
Transition aspect of your movement scene. Inside the brand new aspect, you’re free to create any variety of key frames.
<KeyFrameSet android:id="@+id/my_keys"> <!-- Extra code right here --> </KeyFrameSet>
MotionLayout widget helps many several types of key frames. On this tutorial, we’ll be working with solely two varieties:
KeyPosition frames and
KeyPosition frames are those that show you how to alter the form of the trail. Whereas creating them, be sure to present the ID of the goal widget, a place alongside the timeline, which will be any quantity between Zero and 100, and the specified X or Y coordinates specified as a share. The coordinates can both be relative to the precise X or Y axes or be relative to the trail itself.
The next code exhibits you learn how to create two key frames that power the
ImageView widget to comply with a path that avoids collisions with the button and the search bar:
<KeyPosition app:goal="@+id/actor" app:framePosition="30" app:sort="deltaRelative" app:percentX="Zero.85" /> <KeyPosition app:goal="@+id/actor" app:framePosition="60" app:sort="deltaRelative" app:percentX="1" />
If you happen to run the app now, you must see an animation that appears like this:
You’re, in fact, free so as to add extra key frames. For instance, by including the next key body in the direction of the tip of the timeline, you may make the
ImageView widget comply with a extra wavy path:
<KeyPosition app:goal="@+id/actor" app:framePosition="80" app:sort="deltaRelative" app:percentX="Zero.5" />
Through the use of a
KeyCycle body together with the
KeyPosition frames, you’ll be able to add oscillations to the animation. Whereas creating it, you could once more present the ID of the goal widget, a place alongside the timeline, and the specified worth of the property that has to oscillate forwards and backwards. Moreover, you could configure an oscillator by offering particulars such because the wave form to make use of and the wave interval.
The next code creates a
KeyCycle body that makes use of a sine-wave oscillator to periodically rotate the
ImageView widget by 50 levels:
<KeyCycle app:goal="@+id/actor" app:framePosition="30" android:rotation="50" app:waveShape="sin" app:wavePeriod="1" />
On working the app once more, you must see an animation that appears like this:
7. Make Animated Widgets Interactive
All this whereas, you have been urgent a button to begin the animation. Such a button, nonetheless, just isn’t at all times essential as a result of the
MotionLayout widget means that you can instantly connect contact occasion handlers to the widgets being animated. At present, it helps the on-click and the on-swipe occasions.
As an example, you’ll be able to add the next
OnClick aspect, which targets the
ImageView widget, contained in the
Transition aspect of your movement scene to make the button redundant:
<OnClick app:goal="@+id/actor" app:mode="transitionToEnd"/>
Equally, you need to use an
OnSwipe aspect to permit the consumer to manually drag the
ImageView widget throughout the display screen. Whereas creating the aspect, you could be sure to present the correct drag route and the facet of the widget that ought to act because the drag deal with.
<OnSwipe app:touchAnchorId="@+id/actor" app:touchAnchorSide="prime" app:dragDirection="dragUp" />
If you happen to run the app once more, you must now be capable to drag the
You now know learn how to use the
MotionLayout widget to rapidly add complicated, interactive animations to your Android apps. You possibly can make certain that the animations will run with none lag or jitter on most units, as long as you keep away from nested views.
It is price noting that upcoming releases of Android Studio will embody a visible Movement Editor, which is more likely to additional enhance the usability of the widget.
To be taught extra, do check with the official documentation.