Advanced shared elements with shape morphing | Jetpack Compose Tips
Learning Stats
GER-Niveau
Total Words
Unique Words
Difficulty
Untertitel (174 segments)
DownloadREBECCA FRANKS: Users love screens
that feel fluid and show continuity between transitions.
In a previous video, we covered how
to get started with the basics of shared elements in Jetpack
Compose.
In this tip, we will cover a more advanced example
application of shared elements and how you can also add
moments of delight to your app.
[MUSIC PLAYING]
In Androidify, we are using the new material
shapes that come as part of the Material 3 Expressive updates.
We have two screens, the Creation screen
that shows the camera button and the Camera
screen that shows the camera viewfinder and the related
buttons.
Currently, we've transitioned between the two screens,
but we don't have a nice animation between the two.
So what if we wanted to transform between the Take Photo
button, which is this delicious cookie
shape, to the full-screen square that the camera screen takes on
as a shared element, slowly having the cookie reveal
the camera screen as it grows in size
and transforms to the screen's rectangle shape.
We need to do three things to achieve this animation--
use shared elements to grow from the Photo button
to the camera screen; reveal the camera
screen as the button grows in size;
and clip the shared element to the morphing shape.
So for step 1, we use the same concept
shown in the shared element video that's linked below.
Firstly, we need to make sure that the top level of our
app we are using a SharedTransitionLayout.
We've placed our SharedTransitionLayout
at our top level of the theme in order
to use it all throughout the Androidify app.
We also set a composition local for the SharedTransitionScope
so that we don't need to pass the scope around.
The next step is to ensure that we have an animated visibility
scope, which drives the transition between the two
screens.
We are using Navigation 3 in this sample, which
provides a built-in composition local where
you can access when needed.
Perfect.
Now, we have the correct scope set up.
We can add the sharedBounds modifier onto our content.
We first add it onto the Take Photo button,
passing in the key and the animated visibility
scope from Nav3.
We then add the same modifier onto the full-screen camera
screen composable.
We should have a shared element at this point.
However, we'd like this effect to be a little bit more
sophisticated.
The camera contents to grow from the size
of the originating button to the size of the screen.
It's not the effect that we are going for.
We prefer it to stay in its final end state
and be slowly revealed to the user instead.
We call this pattern the reveal pattern.
The other issue is that the shape isn't morphing
between the two just yet.
So for step 2, let's create a wrapper
to hide away the implementation details
and make the usage neater.
We will call this function sharedBoundsReve
alWithShapeMorph.
We provide in default scopes from the composition locals,
the shared transition scope from the SharedTransitionLayout
and the LocalNavAnimatedContentScope
from Nav3 and switch our usages to use this modifier that
wraps shared bounds instead.
The other values are the same defaults
that the original sharedBounds modifier uses,
but we need to expose them to be able to use them in our usages
too.
To tackle the issue of the camera not revealing,
we need to tell the underlying layout
that it should stay in place and skip the lookahead measurements
and placement.
To do this, we add the skipToLookaheadSize
and skipToLookaheadPosition modifiers.
These two modifiers will ensure that the content placed
after the modifiers will not be animated or moved
when the shared element animation is happening.
Running this, we can see that the animation looks
like a reveal animation instead of growing to the camera
viewfinder.
Right, for the grand finale, the actual shape morphing.
This can be achieved using the new material shapes.
The great thing about these preset shapes
is that they are backed by the AndroidX graphics shape
library, which has built-in morphing capabilities.
This means that we can provide two shapes,
create a morph between the two, and pass in the progress value
and have the shapes transform between the two.
To incorporate the shape transformation,
we need the two shapes passed in,
the resting shape and the target shape.
Each instance of shared bounds needs
both, as the transition shows both elements at the same time
on screen as it transitions.
So we need to ensure that we are matching up
the incoming and outgoing content
with the exact same shape as they transform.
So we update our modifier to take in a resting shape
and target shape as parameters.
We then need to also create the morph object.
We provide the resting shape and the target shape as input
into the morph.
We also need to create a progress value
that animates between 0 and 1 to be able to perform the morphing.
To do this, we tie into the animated visibility scope
transition object and use animateFloat
to animate based on the enter and exit
state of the transition.
For example, when the shared element is fully visible,
we'd like the resting shape to be the shape we use.
So the visible state has the progress set to 0.
OK, we now have the shapes passed in,
the morph object set up, and our progress between the two
shapes in place.
Now we need to figure out how to get
the changing path that will be used
as the clip for the animation.
To do this, we need to create an overlay clip.
We will call ours MorphOverlayClip,
where we pass in the morph and the animated progress value.
We will get to the implementation
of this in just a second.
This clip is provided to the sharedBounds modifier
as the clipInOverlayDuringTransition
variable.
The shape clip will apply during the transition between the two
states when the animation is active.
The MorphOverlayClip implementation
takes in the morph object and the animated progress.
We override the getClipPath function.
This is what the sharedBounds modifier
will call as it's transitioning between the two elements.
First, we need to scale up the morph object
to the size of the area that the animation is performed in.
In this example, we use a matrix to perform the scaling
operations.
We get the max between the width and the height
to scale it uniformly, not to stretch the object.
We then call two path on the morph object
with the animated progress to get
us the morphed path at that particular point
in the animation.
To scale the path up to the size of the area,
we call transform with the matrix
that we created previously, and we translate its offset
to the center of the drawing area.
We then return that path to be used with the shared elements.
Now we just need to make sure that both our call sites
pass in the correct shapes into the content.
On the camera screen, the resting shape
will be the rectangle, and the target shape
will be the cookie nine-sided shape.
The cookie button will have the same, but in reverse.
The resting shape is the cookie nine-sided,
and the target shape is the rectangle.
And that gives us this ultra-fabulous, expressive,
delightful shared element transition
between the two screens.
Oh, and did I mention it's also compatible with predictive back?
You can see, as we slowly pull back,
it animates between the two screens.
And that's it for this tip.
To check out the full code sample,
head to the GitHub repository.
Bye for now.
[MUSIC PLAYING]
Key Vocabulary (50)
toward
"Go to school."
belonging
"Cup of tea."
also
"You and me."
inside
"In the house."
specific
"That book."
A third-person singular pronoun used to refer to an object, animal, or situation that has already been mentioned or is clear from context. It is also frequently used as a dummy subject to talk about time, weather, or distance.
Used to show who is intended to have or use something, or to explain the purpose or reason for an action. It is also frequently used to indicate a specific duration of time.
A preposition used to indicate that people or things are together, in the same place, or performing an action together. It can also describe the instrument used to perform an action or a characteristic that someone or something has.
A conjunction used to compare two things that are equal in some way. It is most commonly used in the pattern 'as + adjective/adverb + as' to show similarity.
Used to identify a specific person, thing, or idea that is physically close to the speaker or has just been mentioned. It can also refer to the present time or a situation that is currently happening.
Used to indicate the starting point, source, or origin of something. It can describe a physical location, a point in time, or the person who sent or gave an item.
The word 'we' is a first-person plural pronoun used to refer to the speaker and one or more other people collectively. It is used as the subject of a sentence or clause.
A modal verb used to talk about future actions, predictions, or promises. It is placed before the base form of a verb to show that something is going to happen later.
An adverb used to emphasize the quality, intensity, or extent of an adjective or another adverb. It indicates that something is very or extremely high in degree.
Used to express physical or mental ability to do something or to show that something is possible. It is also frequently used to ask for or give permission in informal situations.
Sign up to unlock full features
Track progress, save vocabulary, and practice exercises
Description
Rebecca Franks, a Developer Relations Engineer, covers a more advanced example application of shared elements in Jetpack Compose, combining the basics with shape morphing and the new Material...
Kategorien
Ähnliche Videos
Was the Trojan War Fought Over a Rock?
You Stopped Exercising. The Gains That Stuck Around Might Surprise You.
Now in Android: 117 – What’s new in Android development at Google I/O 2025 (part 1)
Now in Android: 123 – Android XR, Jetpack Navigation 3, and more!
Bagged Salad Shouldn’t Exist
English with Lucy