I have a column with a container that acts as a header and a gridview of widgets below. I want only the gridview to be scrollable and that the header will not move and always be displayed.
This is my code:
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
Container(
margin: EdgeInsets.only(left: 24, right: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 22),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Message("Hello, Guest!", size: 32),
Icon(
CustomIcons.statistics,
color: AppColors.blue,
size: 32.0,
),
],
),
SizedBox(height: 14),
Message("What worries you now? Select or Add.", size: 14),
],
),
),
SizedBox(height: 16),
GridView.count(
primary: true,
shrinkWrap: true,
crossAxisCount: 2,
crossAxisSpacing: 40.0,
mainAxisSpacing: 40.0,
padding: const EdgeInsets.all(20.0),
children: _items,
),
],
),
),
);
}
}
When it runs I get a renderflex overflowed error:
When I wrap my gridview in an expanded widget as some answers suggested, the scroll gets out of bounds:
Appreciate the help!
CodePudding user response:
Remove expnaded and wrap your safe area With SingleChildScrollView, and also add phyiscs:ScrollPhysics() in gridview
CodePudding user response:
Wrap your Column with a SingleChildScrollView
, A Column will always try to shrink-wrap its children, using Expanded
tells the GridView
to only take up the available space.
Another alternative is if your GridView
doesn't grow in too much size is to use the shrink-wrap: true
and use physics: const NeverScrollablePhyscis()
, that way the GridView
won't try to grow to infinite size.
CodePudding user response:
You can wrap your Column
inside a SingleChildScrollView
widget to make the whole column scrollable. The Code Should be :
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child:Column(
children: [
Container(
margin: EdgeInsets.only(left: 24, right: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 22),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Message("Hello, Guest!", size: 32),
Icon(
CustomIcons.statistics,
color: AppColors.blue,
size: 32.0,
),
],
),
SizedBox(height: 14),
Message("What worries you now? Select or Add.", size: 14),
],
),
),
SizedBox(height: 16),
SingleChildScrollView(
child: GridView.count(
primary: true,
shrinkWrap: true,
crossAxisCount: 2,
crossAxisSpacing: 40.0,
mainAxisSpacing: 40.0,
padding: const EdgeInsets.all(20.0),
children: _items,
),
),
],
),
),
);
}
}
CodePudding user response:
You need to use a combination of Stack
, ListView
and Column
widgets. Here's how to do it:
return Scaffold(
body: SafeArea(
child: Stack(
children: [
SizedBox(height: 16),
ListView(
shrinkWrap: true,
children: [
GridView.count(
primary: true,
shrinkWrap: true,
crossAxisCount: 2,
crossAxisSpacing: 40.0,
mainAxisSpacing: 40.0,
padding: const EdgeInsets.all(20.0),
children: [
Container(
margin: EdgeInsets.all(20),
color: Colors.red,
height: 200,
width: 200,
),
Container(
margin: EdgeInsets.all(20),
color: Colors.amber,
height: 200,
width: 200,
),
Container(
margin: EdgeInsets.all(20),
color: Colors.blue,
height: 200,
width: 200,
),
Container(
margin: EdgeInsets.all(20),
color: Colors.green,
height: 200,
width: 200,
),
],
),
],
),
Container(
color: Colors.white,
height: MediaQuery.of(context).size.height * 0.2,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 22),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Hello, Guest!"),
Icon(
Icons.ac_unit,
color: Colors.blue,
size: 32.0,
),
],
),
SizedBox(height: 14),
Text("What worries you now? Select or Add."),
],
),
),
],
),
),
);