Implementing Collapsing Toolbars with Slivers in Flutter

In Flutter, creating visually appealing and functional UIs often involves complex scrolling effects. A popular technique is implementing a collapsing toolbar, which transitions from a large header to a smaller, more compact toolbar as the user scrolls. This is usually achieved using Slivers, which provide fine-grained control over scrolling behavior. This article delves into how to implement a collapsing toolbar with Slivers in Flutter.

Understanding Slivers in Flutter

Slivers are scrollable, lazily built pieces of UI that can be composed to create custom scrolling effects. Unlike standard widgets like ListView or GridView, Slivers allow you to build custom scrolling behaviors and effects, such as collapsing toolbars, parallax effects, and more. Some of the commonly used slivers include SliverAppBar, SliverList, and SliverGrid.

Why Use a Collapsing Toolbar?

  • Improved User Experience: Provides a dynamic and engaging scrolling experience.
  • Efficient Use of Screen Space: Transitions between a detailed header and a compact toolbar.
  • Visual Appeal: Adds a professional and modern look to your app.

How to Implement a Collapsing Toolbar with Slivers in Flutter

To implement a collapsing toolbar with Slivers, follow these steps:

Step 1: Set Up a CustomScrollView

Use a CustomScrollView to combine multiple Slivers into a single scrollable view:

import 'package:flutter/material.dart';

class CollapsingToolbarExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          // Slivers will go here
        ],
      ),
    );
  }
}

Step 2: Add a SliverAppBar

The SliverAppBar is the key widget for creating the collapsing toolbar effect. Configure its properties to achieve the desired behavior:

SliverAppBar(
  expandedHeight: 200.0,
  floating: false,
  pinned: true,
  flexibleSpace: FlexibleSpaceBar(
    title: Text('Collapsing Toolbar'),
    background: Image.network(
      'https://via.placeholder.com/400x200',
      fit: BoxFit.cover,
    ),
  ),
),

Key properties explained:

  • expandedHeight: The height of the app bar when it is fully expanded.
  • floating: Determines whether the app bar is visible when the user starts scrolling. Set to false for a traditional collapsing effect.
  • pinned: Whether the toolbar should remain visible at the top when scrolling. Set to true to pin the toolbar.
  • flexibleSpace: A widget that animates as the app bar expands and collapses. Usually a FlexibleSpaceBar.

Step 3: Add Content with SliverList or SliverGrid

Add content to the scroll view using SliverList or SliverGrid:

SliverList(
  delegate: SliverChildBuilderDelegate(
    (BuildContext context, int index) {
      return ListTile(
        title: Text('Item $index'),
      );
    },
    childCount: 20,
  ),
),

Step 4: Combine Slivers in CustomScrollView

Put the SliverAppBar and SliverList together inside the CustomScrollView:

import 'package:flutter/material.dart';

class CollapsingToolbarExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            expandedHeight: 200.0,
            floating: false,
            pinned: true,
            flexibleSpace: FlexibleSpaceBar(
              title: Text('Collapsing Toolbar'),
              background: Image.network(
                'https://via.placeholder.com/400x200',
                fit: BoxFit.cover,
              ),
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return ListTile(
                  title: Text('Item $index'),
                );
              },
              childCount: 20,
            ),
          ),
        ],
      ),
    );
  }
}

Complete Example


import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Collapsing Toolbar Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: CollapsingToolbarExample(),
    );
  }
}

class CollapsingToolbarExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            expandedHeight: 200.0,
            floating: false,
            pinned: true,
            flexibleSpace: FlexibleSpaceBar(
              title: Text('Collapsing Toolbar'),
              background: Image.network(
                'https://via.placeholder.com/400x200',
                fit: BoxFit.cover,
              ),
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return ListTile(
                  title: Text('Item $index'),
                );
              },
              childCount: 20,
            ),
          ),
        ],
      ),
    );
  }
}

Customizing the Collapsing Toolbar

There are many ways to customize the SliverAppBar:

  • Adding a Leading Icon: Use the leading property to add an icon at the start of the toolbar.
  • Adding Actions: Use the actions property to add action buttons to the toolbar.
  • Changing the Background Color: Modify the backgroundColor property.
  • Implementing a Search Bar: Add a search bar within the title or flexibleSpace.
SliverAppBar(
  expandedHeight: 200.0,
  floating: false,
  pinned: true,
  leading: IconButton(
    icon: Icon(Icons.menu),
    onPressed: () {
      // Handle menu press
    },
  ),
  actions: <Widget>[
    IconButton(
      icon: Icon(Icons.search),
      onPressed: () {
        // Handle search press
      },
    ),
  ],
  flexibleSpace: FlexibleSpaceBar(
    title: Text('Collapsing Toolbar'),
    background: Image.network(
      'https://via.placeholder.com/400x200',
      fit: BoxFit.cover,
    ),
  ),
),

Conclusion

Implementing a collapsing toolbar with Slivers in Flutter can greatly enhance the user experience by providing a modern and dynamic UI. By combining CustomScrollView with SliverAppBar and other Slivers, you can create custom scrolling effects that make your app stand out. With the detailed steps and code examples provided, you can start building your own collapsing toolbars today and elevate the design of your Flutter applications.