SliverPersistentHeader Flutter, a sliver whose size varies

SliverPersistentHeader is a sliver whose size varies when we scroll down.

Keeping the above statement in mind, when we scroll to the edge of the viewport, which is opposite to the sliver’s GrowthDirection, the SliverPersistentHeader doesn’t disappear. On the contrary, it adjusts its size when we scroll.

Granted, we can have the same effect with SliverAppBar, and we can make it act like a collapsible toolbar. But, when the CustomScrollView has no centred sliver that changes its size with each scroll, SliverPersistentHeader rescues us.

Even the SliverAppBar may disappear, but SliverPersistentHeader remains in the inner space and adjusts its size.

That’s the reason, why we use SliverPersistentHeader in our Flutter app.

Let us take a look at the first screenshot.

SliverPersistentHeader in Flutter
SliverPersistentHeader in Flutter

In the above image, the outer space is covered by SliverAppBar. However, under that special AppBar, we have our two SliverPersistentHeader defined.

return CustomScrollView(
      slivers: [
        SliverAppBar(
          title: const Text(
            'SliverPersistentHeader Sample',
            style: TextStyle(
              fontFamily: 'Allison',
              fontSize: 60,
              fontWeight: FontWeight.bold,
            ),
          ),
          backgroundColor: Colors.deepPurple,
          expandedHeight: 200,
          flexibleSpace: FlexibleSpaceBar(
            background: Image.network(
              'https://cdn.pixabay.com/photo/2016/09/10/17/18/book-1659717_960_720.jpg',
              fit: BoxFit.cover,
            ),
          ),
        ),
        const ACustomSliverHeader(
          backgroundColor: Colors.amber,
          headerTitle: 'First Sliver Persistent Header Sample',
        ),
        const ACustomSliverHeader(
          backgroundColor: Colors.green,
          headerTitle: 'Second Sliver Persistent Header Sample',
        ),
...

Next, we have created two custom Sliver persistent header widgets in this way.

class ACustomSliverHeader extends StatelessWidget {
  final Color backgroundColor;
  final String headerTitle;
// {Key? key}) : super(key: key);
  const ACustomSliverHeader({
    Key? key,
    required this.backgroundColor,
    required this.headerTitle,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SliverPersistentHeader(
      pinned: true,
      floating: false,
      delegate: Delegate(backgroundColor, headerTitle),
    );
  }
}

The SliverPersistentHeader has a parameter called delegate.

It appears that we have created our own Delegate class that extends the abstract class SliverPersistentHeaderDelegate.

It is something that we can do in this way:

class Delegate extends SliverPersistentHeaderDelegate {
  final Color backgroundColor;
  final String headerTitle;

  Delegate(this.backgroundColor, this.headerTitle);

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return Container(
      color: backgroundColor,
      child: Center(
        child: Text(
          headerTitle,
          style: const TextStyle(
            color: Colors.black,
            fontSize: 20,
          ),
        ),
      ),
    );
  }

  @override
  double get maxExtent => 150;

  @override
  double get minExtent => 60;

  @override
  bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
    return true;
  }

In a separate article we’ll take a detailed look at how we can create our own delegate class that we can use in different slivers.

Since, we have displayed part of code for brevity, you can get the full code at the respective GitHub repository.

Now, as a result, we can scroll down to see the sliver eggect.

SliverAppBar in flutter is disappearing
SliverAppBar in flutter is disappearing

As the SliverAppBar starts disappearing, the Sliver persistent header also starts adjusting its size.

Finally, when we have scrolled to the edge of the viewport inverse the sliver’s GrowthDirection, the SliverAppBar completely disappears and the SliverPersistentHeader shrinks and fist to the screen.

To sum up, not only we’ve put the sliver inside a CustomScrollView, we’ve also put the the other sliver to make our custom scrollable region.

That’s why, we’ve put SliverGrid below two custom SliverPersistentHeader.

 SliverGrid(
          delegate: SliverChildBuilderDelegate(
            (context, index) {
              return Container(
                alignment: Alignment.center,
                color: Colors.orange[100 * (index % 9)],
                child: Text(
                  'grid item $index',
                  style: const TextStyle(
                    fontSize: 15,
                  ),
                ),
              );
            },
            childCount: 30,
          ),
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3,
            mainAxisSpacing: 15,
            crossAxisSpacing: 15,
            childAspectRatio: 2.0,
          ),
        ),

So when we scroll down entirely, the sliver grid item count reaches the number and sliver persistent header shrinks and fits the screen.

SliverPersistentHeader varies its size in flutter
SliverPersistentHeader varies its size in flutter

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

GitHub repository

Technical blog

Twitter

Comments

3 responses to “SliverPersistentHeader Flutter, a sliver whose size varies”

  1. […] We’ve already learned what is SliverAppBar. In addition, we’ve learned how to make collapsing toolbar, what is sliver grid, and sliver persistent head whose size varies. […]

  2. […] We’ve already learned what is SliverAppBar. In addition, we’ve learned how to make collapsing toolbar, what is sliver grid, and sliver persistent head whose size varies. […]

Leave a Reply