Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SliverAppBar doesn't fully collapse with short list

I'm using Flutter's SliverAppBar with SliverList. The app bar works fine with long list, that scroll a lot. However, if I have medium size list with 8 items the app bar only partially collapses until the list runs out of items. It makes logical sense that the scroll stops because there are no more items but it leaves a really nasty effect on the app bar, which is being left in the middle of its transition in to collapsed toolbar.

Is there a way to force the list to scroll up until the toolbar is fully collapsed?

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton.extended(
        label: Text("Start!"),
        icon: Icon(Icons.play_arrow),
        backgroundColor: Colors.orange,
        elevation: 12,
        onPressed: () {
          Routing.navigate(
            context,
            LoggingPage(
              workout: _workout,
              exercises: workoutExercises,
            ),
          );
        },
      ),
      body: CustomScrollView( physics: ScrollPhysics(),
        slivers: <Widget>[
          SliverAppBar(
            actions: <Widget>[
              MaterialButton(onPressed: (){}, child: Text("data"),)
            ],
            expandedHeight: 300,
            pinned: true,
            floating: true,
            snap: true,
            flexibleSpace: FlexibleSpaceBar(
              title: Text(_workout.name),
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              buildSliverListItem,
              childCount: workoutExercises.length,
            ),
          ),
        ],
      ),
    );
  }
like image 815
Jeremi Avatar asked Mar 25 '19 21:03

Jeremi


1 Answers

We can use NestedScrollView, SliverOverlapAbsorber and SliverOverlapInjector based on Code With Andrea's example here

https://github.com/bizz84/slivers_demo_flutter/blob/master/lib/pages/nested_scroll_view_page.dart.

We use a NestedScrollView. First, we embed the SliverAppbar within the headerSliverBuilder with a SliverOverlapAbsorber above the SliverAppBar.

Next, we embed the CustomScrollView within a builder inside the body of the NestedScrollView. We add a SliverOverlapInjector at the top of the body.

return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled){
          return <Widget>[
            SliverOverlapAbsorber(
              handle:
              NestedScrollView.sliverOverlapAbsorberHandleFor(context),
              sliver: SliverAppBar(

                pinned: true,
                //floating: true,
                stretch: true,
                expandedHeight: 300.0,
                flexibleSpace: FlexibleSpaceBar(
                  centerTitle: true,
                  title: const Text('Weather Report'),
                  background: Image.asset(
                    'assets/images/logo1.jpg',
                    fit: BoxFit.cover,
                  ),
                ),
              ),
            ),
          ];
        },
        body: SafeArea(
          child: Builder(
              builder:(BuildContext context) {
                return CustomScrollView(
                  slivers: <Widget>[
                    SliverOverlapInjector(
                      // This is the flip side of the SliverOverlapAbsorber above.
                      handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
                          context),
                    ),
                    SliverList(
                      delegate: SliverChildBuilderDelegate(
                          (BuildContext context, int i){
                            return ListTile(
                              leading: Icon(Icons.wb_sunny),
                              title: i%2 != 1 ? Text('Sunday ${i+1}') : Text('Monday ${i+1}'),
                              subtitle: Text('sunny, h: 80, l: 65'),
                            );
                          },
                        childCount: 5
                      ),
                    ),

                  ],
                );
              }
          ),
        ),
      ),
    );

enter image description here

like image 139
karmelcorn Avatar answered Oct 23 '22 21:10

karmelcorn