To make it easier for users to view a list of items, you may want to hide theapp bar as the user scrolls down the list. This is especially true if your appdisplays a “tall” app bar that occupies a lot of vertical space.

Traditionally, you create an app bar by providing an appBar property to theScaffold Widget. This creates a fixed app bar that always remains abovethe body of the Scaffold.

Moving the app bar from a Scaffold Widget into aCustomScrollViewallows you to create an app bar that scrolls offscreen as you scroll through alist of items contained inside the CustomScrollView.

This recipe demonstrates how to use a CustomScrollView to display a list of items with an app bar on top that scrolls offscreen as the user scrolls down thelist.

Directions

  • Create a CustomScrollView
  • Use SliverAppBar to add a floating app bar
  • Add a list of items using a SliverList

1. Create a CustomScrollView

In order to create a floating app bar, you need to place the app bar inside aCustomScrollView that also contains the list of items. This synchronizes thescroll position of the app bar and the list of items. You may think of theCustomScrollView Widget as a ListView that allows you to mix and matchdifferent types of scrollable lists and widgets together!

The scrollable lists and widgets that can be provided to the theCustomScrollView are known as slivers. There are several types of Slivers,such as a SliverList, SliverGridList, and SliverAppBar! In fact, theListView and GridView Widgets use the SliverList and SliverGrid widgetsunder the hood!

For this example, create a CustomScrollView that contains a SliverAppBar and a SliverList. In addition, you need to remove any app barsyou may be providing to the Scaffold Widget!

  1. Scaffold(
  2. // No appBar property provided, only the body!
  3. body: CustomScrollView(
  4. // Add the app bar and list of items as slivers in the next steps
  5. slivers: <Widget>[]
  6. ),
  7. );

2. Use SliverAppBar to add a floating app bar

Next, add an app bar to theCustomScrollView.Flutter provides theSliverAppBarWidget out of the box. Much like the normal AppBar widget, you can use theSliverAppBar to display a title, tabs, images and more.

However, the SliverAppBar also gives you the ability to create a “floating”app bar that scrolls offscreen as the user scrolls down the list. Furthermore,you can configure the SliverAppBar to shrink and expand as the user scrolls.

To achieve this effect:

  • Start with an app bar that displays only a title
  • Set the floating property to true. This allows users to quickly reveal the app bar when they being scrolling up the list.
  • Add a flexibleSpace widget that will fill the available expandedHeight.
  1. CustomScrollView(
  2. slivers: <Widget>[
  3. SliverAppBar(
  4. title: Text('Floating app bar'),
  5. // Allows the user to reveal the app bar if they begin scrolling back
  6. // up the list of items
  7. floating: true,
  8. // Display a placeholder Widget to visualize the shrinking size
  9. flexibleSpace: Placeholder(),
  10. // Make the initial height of the SliverAppBar larger than normal
  11. expandedHeight: 200,
  12. ),
  13. ],
  14. );

Tip:Play around with the various properties you can pass to the SliverAppBarWidgetand use hot reload to see the results. For example, you can use an ImageWidget for the flexibleSpace property to create a background image thatshrinks in size as it’s scrolled offscreen.

3. Add a list of items using a SliverList

Now that you have the app bar in place, add a list of items to theCustomScrollView. You have two options: aSliverList ora SliverGrid.If you need to display a list of items one after the other, use the SliverListWidget. If you need to display a grid list, use the SliverGrid Widget.

The SliverList and SliverGrid Widgets take one required parameter: aSliverChildDelegate.While this sounds fancy, the delegate is simply used to provide a list Widgetsto SliverList or SliverGrid. For example, theSliverChildBuilderDelegateallows you to create a list of items that are built lazily as you scroll, justlike the the ListView.builder Widget.

  1. // Create a SliverList
  2. SliverList(
  3. // That uses a delegate to build items as they're scrolled on screen.
  4. delegate: SliverChildBuilderDelegate(
  5. // The builder function returns a ListTile with a title that
  6. // displays the index of the current item
  7. (context, index) => ListTile(title: Text('Item #$index')),
  8. // Builds 1000 ListTiles
  9. childCount: 1000,
  10. ),
  11. )

Complete example

  1. import 'package:flutter/foundation.dart';
  2. import 'package:flutter/material.dart';
  3. void main() => runApp(MyApp());
  4. class MyApp extends StatelessWidget {
  5. MyApp({Key key}) : super(key: key);
  6. @override
  7. Widget build(BuildContext context) {
  8. final title = 'Floating App Bar';
  9. return MaterialApp(
  10. title: title,
  11. home: Scaffold(
  12. // No appbar provided to the Scaffold, only a body with a
  13. // CustomScrollView
  14. body: CustomScrollView(
  15. slivers: <Widget>[
  16. // Add the app bar to the CustomScrollView
  17. SliverAppBar(
  18. // Provide a standard title
  19. title: Text(title),
  20. // Allows the user to reveal the app bar if they begin scrolling
  21. // back up the list of items
  22. floating: true,
  23. // Display a placeholder Widget to visualize the shrinking size
  24. flexibleSpace: Placeholder(),
  25. // Make the initial height of the SliverAppBar larger than normal
  26. expandedHeight: 200,
  27. ),
  28. // Next, create a SliverList
  29. SliverList(
  30. // Use a delegate to build items as they're scrolled on screen.
  31. delegate: SliverChildBuilderDelegate(
  32. // The builder function returns a ListTile with a title that
  33. // displays the index of the current item
  34. (context, index) => ListTile(title: Text('Item #$index')),
  35. // Builds 1000 ListTiles
  36. childCount: 1000,
  37. ),
  38. ),
  39. ],
  40. ),
  41. ),
  42. );
  43. }
  44. }

Basic List Demo