The best way to use the out of the field options to get an awesome outcome.
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!
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!
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.
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:
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:
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:
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.
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:
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: