SliverAppBar not scrolling when nested ListView uses a ScrollController

Viewed 297

Minimum reproducible code:

final _controller = ScrollController();

@override
Widget build() {
  return NestedScrollView(
    headerSliverBuilder: (_, __) => [SliverAppBar(expandedHeight: 300)],
    body: ListView.builder(
      controller: _controller, // Removing this solves the issue. 
      itemCount: 100,
      itemBuilder: (_, i) => Text('$i'),
    ),
  );
}

If I scroll my ListView, the SliverAppBar doesn't scroll but if I remove the controller property then it does scroll.

So, how can I use the controller and make the SliverAppBar to scroll with the ListView (i.e. the standard behavior)?


Note: I don't want to use the CustomScrollView as my tree hierarchy won't let me make use of it that well.

2 Answers

You should make sure that the child is wrapped

final _controller = ScrollController();

@override
Widget build() {
  return NestedScrollView(
    headerSliverBuilder: (_, __) => [SliverAppBar(expandedHeight: 300)],
    body: ListView.builder(
      //add this to the child ListView
      shrinkWrap: true
      controller: _controller, // Removing this solves the issue. 
      itemCount: 100,
      itemBuilder: (_, i) => Text('$i'),
    ),
  );
}

Just move the scroll controller to NestedScrollView like this:

Widget build() {
  return NestedScrollView(
    headerSliverBuilder: (_, __) => [SliverAppBar(expandedHeight: 300)],
    body: ListView.builder(
      //add this to the child ListView
      shrinkWrap: true,
      itemCount: 100,
      itemBuilder: (_, i) => Text('$i'),
    ),
    controller: _controller,
  );
}

That worked for me, I had a waterfalls flow using the scroll controller. and I need the sliver appear style.

Related