SECRET OF CSS

Introducing Jetpack Compose’s New Layout: “LookaheadLayout” | by jisungbin | Jul, 2022


Layouts for creating the best animations

0*t3XHE1KeFjwgyo1m
Photo by Robert Katzki on Unsplash

On June 29, a new layout, LookaheadLayout, was introduced with the release of Jetpack Compose 1.3.0-alpha01. To understand the concept of LookaheadLayout, let’s imagine we have an ExpandableFab like below.

Contrary to what we imagined, it is not pretty because there is no animation. Let’s add animation.

Now, the ExpandableFab that we imagined is complete.

1* 4r2aBktW2t vl9ALM9Y1Q

Animations, including the ExpandableFab above, proceed as the start frame, which is the initial state, the animation frame in which the animation is in progress, and the finished frame, which is the final state, are drawn.

So, to implement such an animation in Compose, it seems like the track the animation frame like the principle of drawing the animation above, and draw a new composable that fits each frame.

However, there is no layout that can track these animation frames until version 1.2.0. A layout that emerged to overcome this is called LookaheadLayout.

1*vUSeAzLKjITiH7AHp9B25g
Tossface provided by the Toss team is applied (emoji font)

LookaheadLayout previews the frames to be drawn between start-finish frames, and helps to draw a new layout between start-finish based on the information (measurement, placement) expected to be drawn on that frame.

1*CzfYNBzUjTEw eksBwBo2A

The step of tracing the frames drawn between start-finish frames is called the lookahead step, and the layout to be placed between start-finish according to the information calculated to be drawn in this way in the lookahead step is called the intermediate layout.

The information calculated in the lookahead stage can be received with Modifier.onPlaced, and the intermediate layout can actually be placed through Modifier.intermediateLayout.

So far, we have learned about the concept of LookaheadLayout. Now let’s actually use it.

LookaheadLayout is composable which is in the experimental stage, and it receives LookaheadLayoutScope as the scope of the content.

LookaheadLayoutScope implements Modifier.onPlaced and Modifier.intermediateLayout.

Modifier.onPlaced is called with the calculated values as an argument when the information for placing the intermediate layout is calculated in the lookahead step. The parameters are the LookaheadLayoutCoordinates that are used by LookaheadLayout and this modifier’s composable.

The process of calling Modifier.onPlaced is:

1*9zKbWXw1iJm1vfeyfmyYIA
where the part filled in pink is meaning the placed content

LookaheadLayoutCoordinates received as an argument is an interface that holds the LayoutCoordinates of both the layouts before and after the lookahead stage. With this, can get the calculated offset of the intermediate layout and the offset of the currently laid out content.

Both LookaheadLayoutCoordinates.localLookaheadPositionOf and LookaheadLayoutCoordinates.localPositionOf are used to get the converted offset relative to a specific coordinate. The only difference is that, unlike localPositionOf, localLookaheadPositionOf uses the lookahead position for coordinate calculation.

Now let’s take a look at the rest of the Modifier.intermediateLayout.

Can use Modifier.intermediateLayout to place an intermediate layout based on the information calculated in the lookahead step.

Modifier.onPlaced and Modifier.intermediateLayout is:

1*7zjzHRUS6Sc3PBP9mzGvVA
where the part filled in pink is meaning the placed content

Now, let’s go back to the frame process of ExpandableFab that we saw at the beginning of this article to actually use LookaheadLayout.

1* sJ04inu0SC1IzNC1ySJfg

The animation frame process can now be tracked via a LookaheadLayout, and the size and offset are changing within this animation frame. We can implement this using Modifier.onPlaced and Modifier.intermediateLayout.

To adjust the size, morph the intermediate layout through the measure argument, which is a lambda that provides the size of the intermediate layout with Modifier.imtermediateLayout. To adjust the offset, adjust the content placement based on the offset of the intermediate layout calculated with Modifier.onPlaced.

Let’s first create a Modifier.movement to adjust the offset.

Next, created Modifier.transformation for resizing.

Now, in order to apply the modifiers made in this way, the existing Fab is wrapped with LookaheadLayout and the modifier connected.

The result:

But it didn’t animate the way we wanted it to. It’s because just placed an intermediate layout, but it doesn’t apply any animation. so it ends quickly, and can’t see any difference from the previous one.

1* 93psFafGFlQgtrP 7jhvQ

Animatable can be used for animation processing. Let’s animate the size and offset changes.

Finally, it looks the way we want it to look.

This article introduced LookaheadLayout. By using LookaheadLayout, you can easily implement a lot of animations like a shared element transition.

The full code of ExpandableFab used in the example in this article can be found at the link below.

In addition, as this 1.3.0-alpha01 was released, Compose began to change to an independent versioning system. As of now, only the compiler is separated, and if set the compose compiler version to 1.3.0-alpha01, then can use Kotlin 1.7.0 version.

Thanks for reading.

[View in Korean]



News Credit

%d bloggers like this: