hey guys and welcome back to a new video
if you want to learn how you can make
such a cool transition effect here
using motion layout and comparable
effects with motion layout pretty much
everything you want to do with motion
layout in jetpack compose then you
should watch this video till the end so
you could imagine that this is some kind
of scroll effect here like a collapsing
toolbar just for simplicity i'm using a
slider here
um but i will basically show you how
motion layout for jetpack compose works
because that was integrated with the
last um
constrained layout compose dependency
release like once that got stable that
dependency there's now also support for
motion layout and it's awesome like i
really enjoy using it it seems very
stable even though they
um they said it's still experimental but
we can make pretty cool things with it
in a pretty easy way um it's of course
not very beautiful here but i want to
show you how you can make these move
effects um that it transitions here in a
little arc and that the color changes
those are just typical things you want
to do with motion layout
so
let's jump right into android studio you
create a new project here
and the first thing you want to do is
you want to include this constraint
layout compose dependency version 1.0.0
that includes motion layout motion
layout which uh
of course also exists for xml
is in the end a constraint layout so
what we basically do is
the idea behind motion layout
is we define a start and end state so
the start state would be this and for
that we have these constrained sets so
we basically just have constraints
where we say okay this image is
constrained to the top to the bottom and
to the left
and then this text is just constrained
to the end of this image and also to the
top and bottom here
that's our start constraint set so that
is where our transition starts
and then we define another of this set
for the end state so here these
constraints suddenly change here for
example the um
profile picture is now centered so it's
not
it's it's not left aligned anymore it's
centered and the text actually is below
our profile picture and if we just
provide the start and end constraint set
to motion layout then motion layout will
figure out a way to transition our
composables in this case
um between the between that given a
specific progress value here which we
get from this slider so let's actually
jump right into it it's really not
difficult
i really want to make the same section
here just as an example you can of
course make so much more cool stuff with
motion layout and for that i will have a
composable
which i will call
profile header
and first of all well what do we need
let's just create a motion layout here
you can see there are different
overloads we can pick for that
one takes a motion scene and one takes a
start and end constraint set
so right now
we can define constraint sets
in
compose directly so in kotlin
if you've watched my constraint layout
tutorial in my compose basics playlist
you will know how this works
it's not difficult it's cool however for
our purpose here we're not going to do
this we're actually going to pick this
motion scene the difference is that for
the motion scene
we kind of define all of our
all of our different constraint sets all
of the
transition properties basically what we
want to animate how we want to animate
it we define that in a separate json5
file so json5 is just a new
type of json that's a little bit
different for syntax wise but not really
difficult
and we just defined it in a separate
file basically which views are of which
composables are constrained to which
other composers are too
parent whatever and then we also define
hey please animate the x rotation
from this to this you will see how this
works but that's basically the motion
scene a file in which we define this
so let's pick this
and well right now we don't really have
a motion scene so i would suggest we
actually start with that
so before we can actually go on here in
our compose code we want to go to res
right click
new
android resource directory because i'd
like to put this motion scene in our raw
file a raw folder
this one here so we want to create this
folder
and inside of this raw folder we right
click again create a new file and call
this
motion underscore scene.json5
and in here we are now going to define
this motion scene from scratch because i
think it's very helpful to just go
through this process once to define this
and then
after that once you understood it you
can just copy and paste it from your
other projects and just adjust what you
need but i think it makes sense to just
go through this from scratch here so the
first thing we do is we just create a
normal json object here so just
opening and closing curly braces
now as i said we need to define our
constrained sets that's nothing else
than what we also did in xml with
constraint layout just that we don't
have a visual editor here we just
specify hey we have these types of
composables
and here are the constraints that's
really all we define in here
so we have constrained
sets here
you can see that's a little bit
different here than with a normal json
in normal json syntax we would have
quotation marks here in json5 we don't
have that
then in here
we have basically two different
constraint sets here
on the one hand we have our start
constraint set so the set where our
transition starts
and then we have the end transition set
so that motion load actually knows okay
i will transition or i will animate
between start and end
so let's start with start
and go in here now this block of code we
basically just define the composables
that we have in our start constraint set
so if we take a look here what do we
have
well
on the one hand we have of course our
profile picture that we need to set
constraints for then we have our text
here
and we actually also have this
background so most this is not the the
background of motion layout that's
important because the background is also
animated so the background of motion
layout is actually not visible here that
would be this big thing and that doesn't
change in size
so if we want to actually animate the
background then we need to make it a
separate composable which is just a box
here
so we have three composables that we
need to define constraints here for
let's start with our profile pic and
here we can just give it a our own id so
that's going to be the id that we are
going to
also mention in code then to refer to
that and we can simply open this and now
just define the typical things we would
like to define with constraint layout
such as the width and height so let's
actually say our
profile picture starts at width 40 and
height 40 as well so that would be
actually this one here so it's just a
square and rather small
now we need to define the constraints so
where this actually sticks to and i
assume you know constraint layout here
otherwise please watch my constraint
layout videos first because yeah i think
explaining that here would be the wrong
place
in the end we have of course four
directions we could constrain a
composable too so we have a top start
and and bottom
for the proper picture here all we
really need is
we need to constrain it to
the start and the top and to the bottom
we just add a little bit of margin here
but we don't need to set a constraint
for that
so
we have start constraint and here we
define that actually as oops
as a list
so what we basically say is
we say okay we constrain
the start of the profile picture
to
the parent
start
so that's basically what we say we
constrain the start of profile picture
to the start of our parent
and then we could have one more
parameter which is a six in here which
would just define the margin to the
start of the parent so that's how you
have to understand this
we do the same for the top constraint
which we would then constrain to the
parent
top in this case
and also give it a little bit of margin
here and that's already it for the
constraints for at least the starting
constraints for our profile picture
the next ones is uh other constraints
for a username
so just the the text composable that we
will use
let's define another constraint set here
so now we basically define
how the username is now constrained and
in the end the username start is
constrained to the end of our profile
picture
and the top and bottom
are constrained to the top and bottom of
our profile pictures so we just center
it vertically and that's what we will
define here we're not going to give it a
width and height because then if we
don't do this it will just um
yeah wrap its content which we want for
the text so instead we're just going to
say okay we have a top constraint which
we're going to
constrain to our profile picture
and we don't need to add any margin here
we have a bottom constraint
which will go to the profile pic
bottom
and we're going to have a start
constraint for our username which will
go to
the end of our profile pic
and here we want to have a little bit of
margin 16dp again so that we have that
little gap here and then we're now going
to have one last composable which is for
the box for background for the dark gray
background color here
which will then
yeah just make sure it is just uh
filling the space that it has
so let's
declare that here and here we want to
specify width and a height but what do
we actually pick because the box should
actually only be as high as our other
content and if you're familiar with
constraint layout then there is
something like
fill to constraints like a property in
xml that was when we set something to
0dp like the width or height
just that it fills the space
it has or the constraints actually
occupy and that's what we want to use
here as well and
in this json way of specifying this if
we want to if we if we want a composable
to fill the space it has we use spread
so we spread the width and we spread the
height
and then for the
for all the constraints we can just con
constrain these two our
corresponding parent constraints so the
start will be the parent start
then let's duplicate that a little bit
the end will be parent end
the top one
will be parent top
and the bottom one
will be parent bottom
now for the bottom one i will actually
add a negative margin of 60 dp
which will be
yeah which will make sure that we have
this space down here
which would otherwise look quite ugly so
now that is it for our start constraint
set so now we've defined how our
composables are arranged at the start of
the transition now we want to do the
same for the end transition so we
actually copy this start constraint set
and append it here
and simply call this end
so of course we want to have the same
composables in here the same ids
just that we now want to change the
values so to which values we want to
animate these now well the profile pick
of course should become larger when we
animate it so
this would now be the end state of our
transition and here we now define okay
that's the new size of our profile
picture and motionlight will then
animate in between these values
i will use
a width of 150 here
a height as well
and well the constraints will also
change a little bit
on the one hand the start constraint of
the profile picture will stay at the
parent start just without any margin
because in the end we just want to
center it now between like horizontally
so we will make sure that we have an end
constraint constrained to the parent end
and the top one will remain at the
parent top with a margin of 16dp that's
fine then let's jump to the username and
constrain
so the
top of the username
should actually not be at the profile
picture top anymore because then that
would mean that the top side of a
username would stick to the top of our
profile picture but we want to stick it
we want it to stick to the bottom here
so
we change this to bottom and we add a
little bit of margin so we have this
little space here
and then the
start constraint we have that let's
specify the end constraint which would
be
to the
parent end so here we also
just want to make sure we center it
horizontally and here we can remove the
margin so start profile pick
start actually
actually no not profile pic parent start
of course
so just center horizontally and the top
one will go to the profile picture
bottom
and finally the box constraints our dark
gray box will actually stay exactly the
same way because here we don't really
transition to new values all we really
want this box to do is it should just
yeah just spread the height of our other
composables which it already does now
so now we successfully defined our start
and our and constraint set
however what we did not define yet is
how we want this animation to happen so
when
do we actually want to animate which
values that's what we didn't define
right now it would only really animate
the motion in between these if you want
that then you then you're good then you
don't need any further setup here but
for example if you take a look here we
also animate the color here
as we actually slide
and you can not only animate the color
you can animate so many more values like
the text size
like the rotation you can add more
scaling whatever you can make such cool
animations with motion layout so of
course i want to show you how you can do
this
so below this constraint sets block
right here
we will define another block of code and
that will be called transitions and here
in this transitions block we can define
different types of transitions we want
to have and we are just going to have a
single transition here between our start
and end point
which i'll call default
so this default transition will go from
start
to
end and now when i think about it we
should actually make sure to use these
single quotes for this json file file
i'm not sure if it accepts these uh
double quotation marks but
let's better be sure and uh hit ctrl r
to find and replace we can make a little
backslash and a single quote here i
actually double quote
so we want to replace the double quote
with
single quotes
um or
we no we don't even need this backslash
okay so just we want to replace double
quotes with single quotes say replace
all there we go
fix that one
and then we can go back to our
transitions block here so now we define
that we want a transition from the start
to the end constraint set then we can
define something like a path motion arc
without if you can basically say okay
should this transition start vertically
or horizontally so basically how this
motion arc
yeah is arranged so if you see um
how this transition looks like when we
slide here then it's it's it doesn't
move in a straight line to the new
destination it's actually an arc and
that's what we define here
so we say okay we wanted this to start
horizontally so start horizontal
and then we have one last very
interesting property here that we need
to define that we want to define and
that's called keyframes
so here we can now specify individual
keyframes so basically at which portions
of our transition we want which values
to animate
to what that's basically what we define
here so we have a key attributes
property in here
in which we can now define these
different attributes and how we want
these to animate and change during our
transition for specific composables
let's do this step by step so this is
actually not an object that's a list
here
and in this list we have objects so for
every single kind of attribute we want
to animate here for every single
composer rather
we want to specify how this will happen
so
the way this works is we specify a
target which is a list
in this list we specify the ids that are
affected by these changes we describe
here so for example for the profile
picture
what do we want to happen well here we
can now
actually define our keyframes we do this
by saying frames and i will explain what
this means
and actually for the profile pic we
don't want anything special to happen in
our transition i still want to show you
how this would work so
here for the frames we basically pass a
list
and this list will contain numbers
between 0 and
and what this will do is
it will say okay at 0
of our transition so at the very start
we can now define more properties that
define specific
changes transformation values for our
profile picture so we could for example
say
translation x
is
um actually also a list
50 0. so what this would mean is at zero
percent of our transition at the very
start
we move our profile picture by 50 pixels
to the right and then when we transition
towards a hundred percent
we also remove this translation again so
we animate it towards the value zero so
that's how you can actually extra
animate properties uh during that
transition and you cannot only have zero
and a hundred here you could also say
okay i have zero
thirty
80 and 100 and then you could say okay
when my transition starts it should be
50 uh 50 pixels in translation x then
after 30 of our transition we want
90 pixels to have a translation x value
then 120 and then back to zero so that
would also work you can define a bunch
of keyframes here i will actually um
just leave that at zero and 100 here
remove this
and we will make use of this but not now
i will get back to this keyframes
property here because i will later show
you a problem that we that we will face
and then how we can use these keyframes
to fix this problem
so for now we're actually done with this
motion scene file here and we can jump
back to main activity where we can now
refer to this
since we put that in a raw resource file
we need to of course get that as a
string first of all here in our profile
header
we need the context for that
which you can get with local context
current
and then we can say
val motion scene
is equal to remember
we use our context resources open raw
resource
and we simply pass the raw id of our
motion c
and since we want that as a string
we can say dot
read bytes so we read all the bytes
dot
um decode to string actually let's form
that a bit
to make it more readable like this so
that just gives us the motion scene so
basically what we specify here in this
file as a string it's just a little bit
more beautiful than just putting the raw
string in here we got syntax
highlighting and all that stuff so now
for the motion scene
we can pass
a motion
scene and that takes the content of uh
string
so we can simply pass our motion scene
here
we also need to add an experimental
annotation here so we can hit
no can't hit
control i'll probably we need to specify
this first
so let's see we need a bunch of more
parameters on the one hand the progress
well
let's pass that actually as a parameter
here and then i will explain what this
does
which is a float value
the progress
basically just defines the percentage
value
where we are currently adding our um
animation basically just this what this
slider does here we are at zero percent
then like 10 20
50
100 that would be the progress which
defines how yeah how the animation like
the stage of the current animation
i guess that would be clear
and then what else do we need let's just
attach a modifier here and make sure we
fill the max width
and let's try again hitting alt enter
no still doesn't work
i don't know why
we hover over this yeah let's just add
this annotation not sure why alt enter
didn't work
and in here we now specify our
composables that we have the motion
layout
there is no specific order we need to
use here um
we can just first of all specify
the box so i think yeah the order
actually matters so the box is at the
bottom
um
but let's make sure we actually give
this box a modifier fill max width
and let me format that a bit
like this so we want to fill the whole
width of ours of our motion layout we
want to make sure to give the background
color of our dark gray
and well how do we now know how does
this box know
that it should actually that it is
actually this one this composer here
with this box id with these constraints
well for that we have a modifier
property which is layout id
and here we can just specify this box id
we specified in our motion scene
it's really that easy
then we have a profile picture
composable next of which i simply added
one of my pictures in my drawable folder
feel free to add one of yours i also use
mine
so i will have an image composable
the painter will be in a painter
resource
are the drawable
picture i call it and i will
vomit that a bit
i won't give it a content description
but i will give it a modifier because i
want to clip it of course to a circle
shape
that clip circle shape
i want to give that a little border that
i used um so border
let's set the width of the border to 2dp
import ep
i don't know why it
oh no i wasn't pressing out that might
be why
okay
with this 2dp
color let's set it to color green now we
will make sure this is animated later
and the shape will be circle shape
cool so
and we of course also need to do the
same as here
that we say okay this image
refers to the layout id profile pic
and then one last thing is missing
which is our text
the text here is
just my name your name whoever's name
i will increase the font size to
24 sp import sp
and
we also want to give the modifier
and make sure it has the layout id
username and i would say we just try
this out as it is now it won't be
it won't look as my example we will set
it up like that but i will show you how
it would look right now so in here in
our main activity
we have a
column
we have our profile header
we basically need a
progress state so we can just save our
progress by
remember
mutable state of zero f so initially we
start at zero
import that
has it for our profile header
and then let's have a little bit of
spacing
six so let's say 32 dp actually
and then we have our slider
we can use to change the progress so the
value of that ladder will be progress
and in on value change we say progress
is equal to it
and let's actually also give it a little
bit of
heading
horizontal padding of
32 dp
just like that
nothing very special let's launch this
here on my device
and hopefully everything works hopefully
the syntax of the motion scene is
correct but
we'll see there we go let's wait for
this app to launch
and okay i would need to change the text
color but you can read it
if we change this you can see
it already animates
and that already looks similar to what
we had or what i had in my example so
pretty cool however you might notice
that
the text is overlapping a little bit
with our image here
and that's something we would like to
fix
so how could we fix this well now our
keyframes actually come into play so we
could now say
that during this transition
we simply move our text a little bit to
the right so increase the translation x
of our text here for a few
for like for portion of our transition
and that's what we can do with keyframes
and we of course also want to animate
the color here just to show you how that
would work so let's jump back to android
studio
going inside our home of our motion
scene
to our transitions block
and here in this key attributes block we
want to define that we don't want to do
this for the proper picture because we
want to we want this to happen for the
user name so we specify another block
we say target this time it's the oops
single quotes this time it's the
username
and the frames will be
um 0
50 and 100
and then for the translation x
we specify
0 70 0.
so what does that mean that means
when the frame is at zero percent so at
zero percent of our transition at the
very start
we don't have any x translation because
that would simply not center the view it
would then shift the view in x direction
if we would start with that we don't
want this
then at fifty percent of our transition
our translation x is at its maximum at
70
pixels basically and then towards a
hundred percent we move back to zero
pixels in translation
so if we now actually relaunch this take
a look then if we do this you can see
it's overlapping a lot less so we could
even increase this a little bit more
um but you can see in the middle of the
transition
the text is moved 60 px 70 pixels to the
right because we use this translation x
property and then at a hundred percent
it will then move back to zero pixels
extra translation so that's pretty cool
and we can do so much more cool stuff
with this um with these keyframes so for
example just to show you what's possible
uh we could for example
duplicate this and say we have
rotations at and then we can rotate our
view
around the z axis in this case so for
example
we have 180 degrees here
relaunch this go in here and if we now
do this
you can see
our text is actually moving to 180
degrees and then is moving back to zero
degrees
of course that doesn't look good but
just that you get an impression of what
you can now do with these different
values and there are actually
so many more which they have on their
github page for motion layouting compose
so just go through these play around
it's a lot of fun
of course i'll remove this rotation here
but how do we actually animate the color
because there is no property here for
the color
instead what we need to do is we need to
specify that as a custom property
that means
we
do this here in the constraint sets
we say custom
and here we can now give that an id of
for example background and we can just
specify the or we're actually in the in
the end constraint set so that would be
the color of our
border and text
in the end state so when it's expanded
then let's actually just pick white
so we use the
white color code
we copy this
go to the profile picture start
constraint set
and simply specify the starting color
and i'll just use my green color code
here
and now how do we get this custom
property well in mainactivity
motion layout here
we can simply get this as state so we
have a val
properties
is equal to motion properties
and the id
is
background
because that's how we call this property
and motion layout will now animate this
color
in between this green value and this
white value here
so pretty cool we can now use these
properties
and say okay our image
has a green border right now but we want
the border to be
the color of properties
um value
color
and here we again specify a background
and actually i told you something wrong
we don't want the id to be background
here we want it to be profile pic of
course so here we specify which
properties do we want to get well we
want to get the properties the custom
properties of profile picture
and then using these properties we can
use the individual ids of the custom
block here to get these specific values
like here we use profile pic
and here we use background and then we
can copy this and actually do the same
for our text color
so go here
say color is equal to this
it doesn't matter that is this refers to
the profile picture because the color is
actually the same
if we now relaunch this we should
actually see the color to be animated
you can see it starts at green
and then transitions towards white so
that's pretty cool
and that's how you use motion layout for
jetpack compose um was a quite detailed
video longer than i expected but i think
it's quite important to go through this
in detail because motionlight is not an
easy thing but you can make such cool
effects with that and it's in a really
early stage right now for compose so
depending on when you watch this video
things might change but
the general idea behind that will always
stay the same
so if you want to make cool transitions
definitely consider this it's great it's
an amazing alternative to just manually
transitioning all that so let me know
down below if you used motion layout in
your app before
and if yes for what kind of transition
that would be cool to know because i
think we can give each other quite some
inspiration in regards to what types of
animations you use this for because you
can become so creative with that so let
us know down below in the comments give
this video a like and yeah enjoy your
day see you back in the next video bye
bye