Welcome to another MotionLayout Quickie! This week we'll be exploring MotionLayout
sub-elements!
All examples will be based on us using a simple MotionLayout
with a start and end state and nothing else.
The old way
Before ConstraintLayout alpha 3, when you were modifying something on a view in the start state and also in the end state you had to define ALL your constraints again to maintain all the previous attributes you had set.
For example, let's say in our start state we had an ImageView
and we were going to rotate it 180º
in our end state.
We'd have a MotionScene
that might look a little something like this.
<MotionScene>
...
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/bookCover"
android:layout_width="150dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/bookCover"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:rotation="180"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
</MotionScene>
That's quite a lot of extra stuff! Especially as all we're going to be doing is rotating our ImageView and not changing our positioning.
A little less conversation
Since ConstraintLayout alpha 3 we've been able to utilise constraint sub-elements which let us only define only the things that are changing. There are 4 types of sub-elements:
<Layout>
: layout-related attributes e.g.android:layout_height
,app:layout_constraintTop_toTopOf
<PropertySet>
: attributes likealpha
,visibility
,motionProgress
,visibilityMode
,constraintTag
<Transform>
: attributes likescale
,rotation
,translation
,elevation
,pivot
<Motion>
: attributes likemotionStagger
,pathMotionArc
,transitionEasing
Let's use the <Transform>
sub-element in our example above.
<MotionScene>
...
<ConstraintSet android:id="@+id/start"/>
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/bookCover">
<Transform android:rotation="180" />
</Constraint>
</ConstraintSet>
</MotionScene>
And now it's much smaller! As you can see we can remove all the layout related attributes that we defined before as we don't need to define them. We just rely on the layout attributes that we've already defined in our layout. We don't even need to set anything in our start
constraint set as we'll just rely on the View
default rotation of 0
.
If we want to make something a little more "complex" we can make use of all the sub-elements and produce an ImageView
that moves from top to bottom, rotates 180º
and moves from 20%
alpha to 100%
and decelerates as it moves.
<MotionScene>
...
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/bookCover">
<Layout
android:layout_width="150dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Transform android:rotation="0" />
<PropertySet android:alpha="0.2"/>
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/bookCover">
<Layout
android:layout_width="150dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Transform android:rotation="180" />
<Motion app:transitionEasing="decelerate"/>
<PropertySet android:alpha="1"/>
</Constraint>
</ConstraintSet>
</MotionScene>
And there we have it!
You can find a demo and all the code for this post in the master branch of this repo: https://github.com/mikescamell/Loco-MotionLayout
Is there another feature you like to see in a MotionLayout Quickie? Think I've screwed up? Can you solve a rubik's cube with your tongue? Let me know on Twitter!
Last but not least, check out androiddev.io for the latest blog posts from Android developers around the world!