SliverAppBar in Flutter with Example
By: Baradwaj Varadharajan
Tags: Flutter Widget, Flutter, Flutter App, Flutter Sliverappbar, Flutter App Development

SliverAppBar is particularly used in order to produce Custom Scroll of the AppBar along with the scroll direction that the user is scrolling. The normal AppBar is going to be a static bar at the top and be present whenever the Body is scrolled. The SliverAppBar on the other hand still performs the same task of an AppBar but the Scroll action is also going to affect the height of the AppBar.

The need for a Material Animation to create better-looking Applications gives the SliverAppBar a better usage in the Flutter Widget list. This tutorial covers all the important attributes and available combinations to create better-looking SliverAppBars in your next Flutter App.

SliverAppBar — Understanding the Basics

To make use of the SliverAppBar in the Flutter Application, use the below class in any parent Widget. Using the Parent as CustomScrollView widget gives you the option to directly call the SliverWidgets to produce good looking Scroll Animations.

Same Code to showcase how the parent widget should be is given below,

import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: 'Androidmonks', home: Scaffold( body: CustomScrollView( slivers: <Widget>[ SliverAppBar() ], ), ) )); }

The SliverAppBar class is required to create that Custom Sliding Like Appbar to the Application. Note how the SliverAppBar widget is actually inside a Widget Like CustomScrollView which provides the Slivers attribute.

There are a lot of attributes that this Widget class holds, all of them along with their action is listed below.

SliverAppBar — Properties explained

actions

Similar to the attribute in Appbar. This lets you create any widget to the right of the AppBar Title. It can take in any number of widgets and it is important to have it minimal and not clutter the AppBar too much.

To create a simple Icon to the right of the AppBar title, you can follow the code below.

import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: 'Androidmonks', home: Scaffold( body: CustomScrollView( slivers: <Widget>[ SliverAppBar( actions: <Widget>[ Icon(Icons.volume_off) ], ) ], ), ) )); }

This creates the App which looks like,

title

The title attribute lets you define a Text() widget that holds a Title to the SliverAppBar.This is the attribute similar to the AppBar where the Title holds the name of the Application or the name of the screen for example. You can define the title by like the following code,

import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: 'Androidmonks', home: Scaffold( body: CustomScrollView( slivers: <Widget>[ SliverAppBar( title: Text("Sample Slivers"), ) ], ), ) )); }

leading

The leading attribute lets you define any widget to the left of the attribute. This is the place where mostly the Menu Drawers are placed. You can define any widget in this place. To create a simple Leading attribute, use the following code.

import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: 'Androidmonks', home: Scaffold( body: CustomScrollView( slivers: <Widget>[ SliverAppBar( title: Text("Sample Slivers"), leading: Icon(Icons.menu), ) ], ), ) )); }

This created the leading Widget which looks like,

backgroundColor

The backgroundColor attribute as the name suggests lets you define a Background Color to the SliverAppBar. Takes in the Color class as its value.

To create a backgroundColor take the example of the below code,

import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: 'Androidmonks', home: Scaffold( body: CustomScrollView( slivers: <Widget>[ SliverAppBar( title: Text("Sample Slivers"), leading: Icon(Icons.menu), backgroundColor: Colors.orangeAccent, ) ], ), ) )); }

This creates the background of the AppBar which looks like

bottom

The bottom attribute is pretty important as it creates a space to the Bottom of the Title and lets you define any widget as required in that position. It takes in the value of the PreferredSizeWidget, check out the below code to understand what the bottom attribute does.

import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: 'Androidmonks', home: Scaffold( body: CustomScrollView( slivers: <Widget>[ SliverAppBar( title: Text("Sample Slivers"), leading: Icon(Icons.menu), backgroundColor: Colors.orangeAccent, bottom: PreferredSize(child: Icon(Icons.linear_scale,size: 60.0,), preferredSize: Size.fromHeight(50.0)), ) ], ), ) )); }

This creates the bottom which looks like,

brightness

As the name suggests, it is going to take in the value of the brightness that the AppBar is going to be in. It is preferably set along with the backgroundColor attribute we saw above. If not, then the AppBar might look odd in terms of creating good looking UI.

Sample Light Brightness will look like,

import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: 'Androidmonks', home: Scaffold( body: CustomScrollView( slivers: <Widget>[ SliverAppBar( title: Text("Sample Slivers"), leading: Icon(Icons.menu), backgroundColor: Colors.orangeAccent, brightness: Brightness.light, ) ], ), ) )); }

expandedHeight

This attribute lets you define the maximum height that the AppBar can expand to when the scroll is done. The height has to be defined in double value. Take a look at the below example,

import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: 'Androidmonks', home: Scaffold( body: CustomScrollView( slivers: <Widget>[ SliverAppBar( title: Text("Sample Slivers"), leading: Icon(Icons.menu), backgroundColor: Colors.orangeAccent, expandedHeight: 90.0, ) ], ), ) )); }

This makes the app which looks like,

flexibleSpace

Flexible Space is used to create a widget which is stacked behind the toolbar and the tabbar. It’s height will be the same as the app bar’s overall height.

This is particular useful if the Widget needs to be scrolled inside the AppBar itself. Sample Code example is given below,

import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: 'Androidmonks', home: Scaffold( body: CustomScrollView( slivers: <Widget>[ SliverAppBar( title: Text("Sample Slivers"), leading: Icon(Icons.menu), backgroundColor: Colors.orangeAccent, flexibleSpace: ListView( children: <Widget>[ Text("Sample 1"), Text("Sample 2"), Text("Sample 3") ], ), ) ], ), ) )); }

This creates a flexible space which looks like,

floating

A very important attribute, which lets you create a Floating AppBar on top of the ListView which can be scrolled. To understand how the floating attribute works, check the below code example,

The floating attribute takes in a boolean value. If true, the AppBar floats as soon as the list is scrolled down, If False the AppBar doesn’t appear unless the top of the List appears.

The difference between floating:true & floating:false is very subtle. The below example tries to bring that difference out.

We have additionally used a SliverList and created a List of Items to perform the Scroll Action.

import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: 'Androidmonks', home: Scaffold( body: CustomScrollView( slivers: <Widget>[ SliverAppBar( title: Text("Sample Slivers"), leading: Icon(Icons.menu), backgroundColor: Colors.orangeAccent, floating: true, ), SliverList( delegate: SliverChildListDelegate([ ListTile(leading: Icon(Icons.volume_off), title: Text("Volume Off"),), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ]), ) ], ), ) )); }

This creates a Floating SliverAppBar which looks like,

When Floating is set to True, the following scroll happens,

pinned

Pinned attribute lets the AppBar either be pinned at the start and only lets the Scroll take place. If set to false, the Scroll will take place but the AppBar acts according to the Scroll Direction.

See the code example below to understand what the pinned attribute does,

import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: 'Androidmonks', home: Scaffold( body: CustomScrollView( slivers: <Widget>[ SliverAppBar( title: Text("Sample Slivers"), leading: Icon(Icons.menu), backgroundColor: Colors.orangeAccent, pinned: true, ), SliverList( delegate: SliverChildListDelegate([ ListTile(leading: Icon(Icons.volume_off), title: Text("Volume Off"),), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ]), ) ], ), ) )); }

When Pinned is set to False,

snap

Snap is similar to Floating attribute, except if this attribute is set to true, the AppBar snaps into view, instead of scrolling! A very small change can provide a better animation on the Application. The snap requires that the Floating attribute is set only then the animation can be seen clearly.

Take a look at the code example below and the same application to understand how this works.

import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: 'Androidmonks', home: Scaffold( body: CustomScrollView( slivers: <Widget>[ SliverAppBar( title: Text("Sample Slivers"), leading: Icon(Icons.menu), backgroundColor: Colors.orangeAccent, floating: true, snap: true, ), SliverList( delegate: SliverChildListDelegate([ ListTile(leading: Icon(Icons.volume_off), title: Text("Volume Off"),), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_mute), title: Text("Volume Mute")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ListTile(leading: Icon(Icons.volume_down), title: Text("Volume Down")), ]), ) ], ), ) )); }

Setting snap to True creates the AppBar which looks like,

primary

If there are multiple AppBars present, you can set the Primary attribute to True to let the Engine decide that, this AppBar occupies the Top Place and will act as the primary AppBar.

automaticallyImplyLeading

This attribute takes in a Boolean value and denotes if the Leading widget can be implied or instead it can be left empty if the Leading widget is not defined.

SliverAppBar — Conclusions

Slivers are very unique to Flutter and can be very useful in building material design UIs easily. Catch also the following Sliver Widgets that are available in Flutter.

SliverList

SliverGrid

ScrollNotification

IndexedSemantics

Drop in your comments below.

“Happy Coding”

Also Read Spinner in Android — Implementation and Overview