Making a Collapsing TopAppBar with Jetpack Compose | by Katie Barnett | Dec, 2022


I used to be just lately constructing an app in Jetpack Compose and when laying out my major scaffold I wished a collapsible prime app bar, much like CoordinatorLayout from the view based mostly UI system. I discovered that when trying on-line on how to do that, many of the instance implementations in different Medium posts had been very customized, and never utilizing LargeTopAppBar in any respect. The official documentation was slightly scant on the topic so I believed my investigations could also be of use to others!

LargeTopAppBar, no collapsing in any respect

First, we have to begin off with a normal LargeTopAppBar in a Scaffold with a listing of content material:

Now, to make it collapse we have to add a scroll behaviour and join this behaviour to our record in order that when the record scrolls, the highest app bar is aware of to break down. This scroll behaviour is created utilizing TopAppBarScrollBehaviour. There are a number of default outlined sorts you should utilize, I’ll show these under, however for the second I’ll use TopAppBarDefaults.exitUntilCollapsedScrollBehavior(). That is created and added to the LargeTopAppBar definition and in addition as a modifier on the Scaffold to the scrollable content material (the LazyColumn):

And the outcome, because the content material is scrolled, the highest app bar is collapsed to a normal TopAppBar!

Collapsing LargeTopAppBar

Fairly easy proper? Nicely, we are able to add a bit extra fashion and customisation…

If you’re utilizing Materials theming, then the highest app bar title styling will replace together with the collapse behaviour. However if you’re utilizing customized styling in your app the fashion will stay static all through the scroll. For instance:

So within the above, we’ve a font dimension set and colors for the TopAppBar container (containerColor), the title (titleContentColor) and the icons (navigationIconContentColor and actionIconContentColor). We will additionally set the collapsed background color with scrolledContainerColor. When that is run, we get the collapsing prime app bar, however the color and title textual content doesn’t change (in my instance case, rendering them invisible). Sadly there isn’t a scrolled model of the title or icon content material colors.

Customized styling, however when collapsed the title and icons are invisible!

To repair this we are able to faucet into the TopAppBarState collapsedFraction worth to find out the transition level:

As quickly because the collapsed fraction passes the midway level (0.5) we modify the color:

Color change, however font dimension staying the identical

We will make this higher for efficiency by changing our collapsedFraction examine through the use of derivedStateOf to minimise the recompositions required (though, for this easy instance there won’t be a lot distinction should you don’t use it).

For extra particulars on when to make use of derivedStateOf take a look at this weblog put up.

Now what in regards to the textual content dimension? Once more, we are able to make use of the collapsedFraction and transition between the 2 font sizes:

As a result of we wish the precise collapsed fraction worth, the derivedStateOf received’t assist right here.

Giving a closing outcome:

Font and colors transitioning properly!

You may get much more customized right here in case your styling transitions are extra elaborate by checking the collapedFraction towards different values (e.g. not simply midway) or among the different offsets included within the TopAppBarState object.

As talked about above, there are a number of scroll behaviours accessible for use for collapsing prime app bars. These are analogous to the scrollFlags from the view system (examples illustrated effectively on this weblog put up). We’ve got the next accessible to us in Jetpack Compose:

  • pinnedScrollBehavior
  • enterAlwaysScrollBehavior
  • exitUntilCollapsedScrollBehavior

pinnedScrollBehavior

As you possibly can guess from the identify, pinnedScrollBehavior doesn’t scroll or collapse the TopAppBar in any respect, it retains it on the prime (certainly, as if there was no scroll behaviour set in any respect). The scrolledContainerColor worth shall be ignored and because the content material scrolls the background color won’t change. You can’t use the collapsedFraction both as this can stay static.

The opposite two have barely completely different behaviours (from the documentation):

enterAlwaysScrollBehavior

…will instantly collapse when the content material is pulled up, and can instantly seem when the content material is pulled down.

exitUntilCollapsedScrollBehavior

…will instantly collapse when the nested content material is pulled up, and can increase again the collapsed space when the content material is pulled all the best way down.

That is simpler to see aspect by aspect:

Scroll behaviours aspect by aspect

Advert you possibly can see, enterAlwaysScrollBehavior will instantly snap seem on scroll up or down whereas the exitUntilCollapsedScrollBehavior will increase steadily on scroll. Which one you utilize will depend on your usecase.

Each enterAlwaysScrollBehavior and exitUntilCollapsedScrollBehavior let you additionally specify snap and fling animation specs to additional customise the collapse animations.

What occurs when our content material will not be a normal record, as a substitute maybe one other giant composable? However the collapsable toolbar impact remains to be wished?

Right here, we are able to add a verticalScroll modifier to the only element with a remembered scroll state that may permit the nestedScrollConnection to choose up the scrolling motion.

Only a single merchandise can nonetheless set off the scroll. Though, in an actual instance you’ll solely want this in case your content material was giant and wanted to have the ability to use the additional house given by a collapsed toolbar.

A closing case to think about is if you’d like your TopAppBar to vary color even when it isn’t a collapsing one (for instance, when the pinned scroll behaviour or no scroll behaviour is outlined). Right here, making an attempt to make use of scrolledContainerColor as we used above can have no impact. As an alternative, we are able to use a derived worth (to scale back the variety of recompositions, see above) to resolve when a scroll has occurred.

For a pinnedScrollBehavior you should utilize the contentOffset . Technically you possibly can simply examine that it doesn’t equal zero, however in my expertise this sparkles a bit too rapidly if the person solely scrolls a tiny quantity so utilizing a small buffer works higher:

If there isn’t a scroll behaviour outlined then you should utilize the LazyListState to detect a scroll:

As soon as we scroll previous the primary merchandise, the color modifications.

This similar method may very well be utilized to extra styling choices and in addition used with the scrollState used within the single merchandise verticalScroll modifier, in that case:

So there you have got it, it’s fairly simple to create a collapsing prime app bar with constant, fluid transitions with out resorting to tremendous customized code.

To see some examples of the code above, take a look at my Github Experiments repository right here:

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles