Flutter NestedScrollView with SliverAppBar Leaves Extra Space Underneath
I'm using a NestedScrollView
with a SliverAppBar
that has a search bar as its title. The app bar collapses correctly, but there’s extra white space underneath it when scrolling.
Scaffold(
body: NestedScrollView(
floatHeaderSlivers: true,
headerSliverBuilder: (context, innerBoxIsScrolled) => [
SliverAppBar(
floating: true,
toolbarHeight: kToolbarHeight,
title: Searchbar(
searchController: _searchController,
filterItems: _filterItems,
),
),
],
body: SafeArea(
child: GridView.builder(
padding: const EdgeInsets.all(10),
itemCount: filteredItems.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
childAspectRatio: 1.2,
),
itemBuilder: (BuildContext context, int index) {
final item = filteredItems[index].data() as Map<String, dynamic>;
return Card(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(item['Data'] ?? 'No Data'),
Text('Category: ${item['Category'] ?? 'Unknown'}'),
],
),
),
);
},
),
),
),
);
SafeArea
(worked, caused content to overlap the status bar).How can I remove the extra space without breaking the layout?
The issue in your code coming from the default top padding
in the GridView
widget. To resolve this, do this:
SafeArea
widget from around the GridView
.padding
of the GridView
by overriding its default padding
.Before :
padding: const EdgeInsets.all(10),
After :
padding: const EdgeInsets.only(top: 0, right: 10, left: 10, bottom: 10),
You can also change the value of the expandedHeight
to reduce the expanded Height of the SliverAppBar
widget <------ expandedHeight: 0.0,
For the SafeArea
widget, you can wrap the Scaffold
or NestedScrollView
with it, but avoid wrapping the GridView
directly with SafeArea
. This ensures proper spacing without interfering with the GridView
's layout.
Full Code After Overriding:
SafeArea( <--------- Move to Here
child: Scaffold(
body: NestedScrollView( <-------- Or Move to Here
floatHeaderSlivers: true,
headerSliverBuilder: (context, innerBoxIsScrolled) => [
SliverAppBar(
floating: true,
toolbarHeight: kToolbarHeight,
expandedHeight: 0.0,
backgroundColor: Colors.amber,
title: Searchbar(
searchController: _searchController,
filterItems: _filterItems,
),
),
],
body: GridView.builder(
padding: const EdgeInsets.only(
top: 0, <------- Use the top padding you want
right: 10,
left: 10,
bottom: 10,
),
itemCount: 8,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
childAspectRatio: 1.2,
),
itemBuilder: (BuildContext context, int index) {
final item = filteredItems[index].data() as Map<String, dynamic>;
return Card(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(item['Data'] ?? 'No Data'),
Text('Category: ${item['Category'] ?? 'Unknown'}'),
],
),
),
);
},
),
),
),
);