Search code examples
flutterflutter-slivernestedscrollview

SliverPersistentHeader without using CustomScrollView


I had a CustomScrollView which looked like:


CustomScrollView(
  slivers: [
    SliverPersistentHeader(
      floating: true,
      delegate: MyPersistentHeaderDelegate(),
    ),
    SliverList(...),
  ],
)

Because I had to change the layout to use masonry layout I am using flutter_staggered_grid_view packages MasonryGridView. The problem is it does not support slivers and therefor i cannot use it in CustomScrollView.

The question is how can I now still use my SliverPersistentHeader (/Delegate) without using a CustomScrollView?

Ive tried using a NestedScrollView but all the examples only show how it works with CustomScrollView:

NestedScrollView(
  floatHeaderSlivers: true,
  headerSliverBuilder: (BuildContext _, bool innerBoxIsScrolled) {
    return <Widget>[
        SliverOverlapAbsorber(
            handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
            sliver: SliverPersistentHeader(
                delegate: MyPersistentHeaderDelegate(),
                floating: true,
            ),
        ),
    ];
  },
  body: CustomScrollView(
    sliver: [
        SliverOverlapInjector(handle: handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context)),

        // wont work in sliver because it uses its own scroll view
        MasonryGridView.builder(),
    ]
  )
),   



Solution

  • Actually you can use the SliverMasonryGrid widget inside a CustomScrollView, as explained in flutter_staggered_grid_view's wiki.

    Here's a code sample inspired by the documentation that has been working well for me:

    Code sample

    class SliverMasonryPage extends StatelessWidget {
      const SliverMasonryPage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: CustomScrollView(
            slivers: [
              SliverPersistentHeader(
                floating: true,
                delegate: MyPersistentHeaderDelegate(),
              ),
              SliverMasonryGrid.count(
                childCount: 100,
                crossAxisCount: 4,
                itemBuilder: (_, i) => Container(
                  margin: const EdgeInsets.all(8),
                  padding: const EdgeInsets.all(16),
                  alignment: Alignment.center,
                  decoration: BoxDecoration(
                    color: Colors.blue,
                    borderRadius: BorderRadius.circular(12),
                  ),
                  child: Text('$i'),
                ),
              ),
            ],
          ),
        );
      }
    }