I'm up to making a screen like on the pic
I'd like to add scroll for gridview, but the trouble now is I don't really understand how to achieve that. When I wrap Grid with SingleChildGridView, I've got an error that bottom overflowed. Example is on the second screen:
Obviously, it's happening as the GridView is a part of Column which causes the error. But how can I find a wayaround to avoid wrapping the column with let's say singlechildscrollview and at the same time making scrollable only GridView ? Here is my code:
Scaffold(
appBar: HomeAppBar(),
bottomNavigationBar: CustomNavBar(),
backgroundColor: Colors.white,
body: Padding(
padding: const EdgeInsets.only(left: 10, right: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Hemendra',
style: Theme.of(context).textTheme.displaySmall
),
Padding(
padding: EdgeInsets.only(top: 5),
child: Text(
'Welcome to Laza.',
style: Theme.of(context).textTheme.bodyMedium
),
),
Searchbox(),
BlocBuilder<ProductBloc, ProductState>(
builder: (context, state) {
if (state is ProductLoaded) {
return Padding(
padding: const EdgeInsets.only(top: 15.0),
child: SingleChildScrollView(
child: GridView.builder(
shrinkWrap: true,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
mainAxisSpacing: 10,
crossAxisSpacing: 10,
mainAxisExtent: 300,
crossAxisCount: 2,
),
itemCount: state.products.length,
itemBuilder: (BuildContext ctx, index) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Stack(
children: [
GestureDetector(
onTap: () {
BlocProvider.of<ProductDetailsBloc>(
context)
.add(ProductDetailsEvent(
state.products[index]));
Navigator.pushNamed(
context, '/product_details');
},
child: Container(
height: 240,
child: Image.network(
state.products[index].imageUrl, fit: BoxFit.fill,),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
IconButton(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
hoverColor: Colors.transparent,
icon: Image(
image: AssetImage('heart.png'),
),
onPressed: () {},
),
],
),
],
),
Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 5),
child: Row(
children: [
Expanded(
child: Text(
maxLines: 2,
state.products[index].name,
style: Theme.of(context).textTheme.bodySmall
),
),
],
),
),
Padding(
padding: EdgeInsets.only(top: 5),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
maxLines: 2,
"\$"
state.products[index].price
.toString(),
style: TextStyle(
color: HexColor('1D1E20'),
fontWeight: FontWeight.w600),
),
],
))
],
),
],
);
},
),
),
);
}
return Center(
child: CircularProgressIndicator(),
);
},
)
],
),
),
);
}
}
CodePudding user response:
remove SingleChildScrollView
and warp you BlocBuilder
with Expanded widget .
so you code widget inside Scaffold body like this
Column(
children: [
searchBox(),
SizedBox(height:70, child: horizontalBrandList()),
Expanded(child: BlocBuilder(...))
],
)
created code similar UI code for better understanding update your code accordingly:
Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//SEARCH BAR
const TextField(decoration: InputDecoration(hintText: "Search")),
const SizedBox(height: 12),
// HORIZONTAL LIST VIEW
SizedBox(
height: 50,
child: ListView(
scrollDirection: Axis.horizontal,
children: List.generate(
10,
(i) => Container(
width: 50,
color: Colors.accents[i % 16],
alignment: Alignment.center,
child: Text('$i'),
),
),
),
),
const SizedBox(height: 12),
// GRID LISTVIEW
Expanded(
child: GridView.builder(
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: MediaQuery.of(context).size.width * 0.5,
childAspectRatio: 0.8,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
),
itemCount: 20,
itemBuilder: (BuildContext ctx, index) {
return Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.amber,
borderRadius: BorderRadius.circular(15)),
child: Center(child: Text(index.toString())),
);
},
),
)
],
),
)
You are adding ListView
inside Column
so You need to wrap with with Expanded Widget
. in ListView contains own ScrollController
so no need to wrap it with external SingleChildScrollView