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,
),
),
],
),
);
}
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
),
),
],
);
}
),
),
),
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With