I'm New to flutter I want to make this design , it take me awhile to find what to use , but ever time i try to code it and use Listview it give me error ,or the card dont aligns to Gridview.
Try below code hope its helpful to you.refer GridView here
Center(
child: GridView.builder(
shrinkWrap: true,
padding: const EdgeInsets.symmetric(horizontal: 30),
itemCount: 4,
itemBuilder: (ctx, i) {
return Card(
child: Container(
height: 290,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20)),
margin: EdgeInsets.all(5),
padding: EdgeInsets.all(5),
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Image.network(
'https://tech.pelmorex.com/wp-content/uploads/2020/10/flutter.png',
fit: BoxFit.fill,
),
),
Text(
'Title',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Row(
children: [
Text(
'Subtitle',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
),
),
],
)
],
),
],
),
),
);
},
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.0,
crossAxisSpacing: 0.0,
mainAxisSpacing: 5,
mainAxisExtent: 264,
),
),
),
Your result screen->
You can use Gridview and return a Card of your custom style in Gridview Builder I will build your Required Design.
Here is the GridView Official Documentation.
[Documentation1
Related
I am trying to build a GridView that adjusts its height automatically according to the data provided. However, I am encountering a problem where an additional line (Top Discount of the Sale) appears after the rating bar for some products, but the space for that line is not reserved for other products that do not have it. As a result, I get a RenderFlex error when I try to implement this. How can I properly handle this situation?
GridView.builder(
padding: const EdgeInsets.all(12.0),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 6.0,
childAspectRatio: .60,
mainAxisSpacing: 6.0,
),
itemCount: state
.productListModel!.productModel!.length,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
return InkWell(
splashFactory: NoSplash.splashFactory,
onTap: () {
Helper.push(
context,
ProductView(
productId: state.productListModel!
.productModel![index].sId,
));
},
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Stack(
alignment:
Alignment.bottomRight,
children: [
SizedBox(
width: WidgetStyles()
.theWidth(context),
height: WidgetStyles()
.theHeight(
context) /
4,
child: ImageView(
imageUrl: state
.productListModel!
.productModel![index]
.photos![0],
fit: BoxFit.contain,
),
),
Positioned(
right: 5,
bottom: 5,
child: Container(
padding:
const EdgeInsets
.all(8.0),
decoration:
const BoxDecoration(
color: Colors
.white,
shape: BoxShape
.circle),
child: InkWell(
onTap: () async {
String deepLink = await FirebaseDynamiclinkService
.createDynamicLink(
true,
state
.productListModel!
.productModel![
index]
.sId!);
log(deepLink);
Helper.shareProduct(
context,
'MyEComApp\n♥️ Proudly made for kerala\n\n${state.productListModel!.productModel![index].productname!}\n${state.productListModel!.productModel![index].seller!.organization!}\n*INR ${state.productListModel!.productModel![index].price!}*\n$deepLink',
state
.productListModel!
.productModel![
index]
.photos![0]);
},
child: const Icon(
Icons.share,
size: 18,
),
),
))
],
),
Helper.allowHeight(context, 5.0),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Flexible(
child: Text(
state
.productListModel!
.productModel![
index]
.productname!
.toString(),
overflow:
TextOverflow.clip,
maxLines: 1,
style:
const TextStyle(
fontSize: 13,
fontWeight:
FontWeight.w500,
),
),
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Flexible(
child: Text(
state
.productListModel!
.productModel![
index]
.seller!
.organization!
.toString(),
overflow:
TextOverflow.clip,
style: TextStyle(
fontSize: 10,
color: AppColors
.greyAA,
fontWeight:
FontWeight.w500,
),
),
),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Text(
"\u{20B9} ${state.productListModel!.productModel![index].price!}",
style: TextStyle(
fontSize: 14,
color:
AppColors.black,
fontWeight:
FontWeight.bold,
),
),
Helper.allowWidth(
context, 15),
state
.productListModel!
.productModel![
index]
.price !=
state
.productListModel!
.productModel![
index]
.orginalprice
? Text(
"\u{20B9} ${state.productListModel!.productModel![index].orginalprice}",
maxLines: 1,
style:
const TextStyle(
overflow:
TextOverflow
.ellipsis,
decoration:
TextDecoration
.lineThrough,
fontSize: 14,
color:
Colors.red,
fontWeight:
FontWeight
.bold,
),
)
: const SizedBox
.shrink(),
],
),
const SizedBox(height: 8),
],
),
]),
);
},
// separatorBuilder: (context, index) {
// return const SizedBox(
// width: 10.0,
// );
// },
);
i would like to use StaggeredGridView plugins, this is my code that i've tried to use and it work properly that you might needed to create a responsive gridview that contain sort list of data
Padding(
padding: const EdgeInsets.fromLTRB(8, 8, 8, 0),
child: SizedBox(
width: double.infinity,
child: StaggeredGridView.countBuilder(
padding: EdgeInsets.zero,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
staggeredTileBuilder: (index) => const StaggeredTile.fit(1),
mainAxisSpacing: 10,
crossAxisCount: 2,
crossAxisSpacing: 10,
itemCount: ...,
itemBuilder: (ctx, i) {
....
},
),
),
)
this is my program but it shows error gridview.builder is not scroll so it shows error
in this gridview it is not working properly it shows error
GridView.builder(
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: 4,
itemBuilder: (BuildContext context, int index){
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Stack(overflow: Overflow.visible,
alignment: Alignment.center,
children: [
Container(
height: 200.0,
width:170.0,
padding: EdgeInsets.only(bottom: 24.0),
decoration: BoxDecoration(
color: kLightGreyColor,
borderRadius: BorderRadius.circular(32.0),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children:[
Text("Name", style: TextStyle(fontSize: 16.0,
fontWeight: FontWeight.w600,
color: klightFontColor), ),
SizedBox(height: 12.0,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children:
List.generate(5, (index) => Image.asset("assets/images/star.png", height: 20.0,))
),
SizedBox(height: 12.0,),
Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
"60 \nMin",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w400,
color: klightFontColor,
),
),
Column(
children:List.generate(6, (index) => Container(
height: 2.0,
width: 2.0,
margin: EdgeInsets.only(bottom: 2),
decoration: BoxDecoration(
color: kDarkGreyColor,
borderRadius: BorderRadius.circular(2.0),
),
))
),
Text(
"Hard \nLV1",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w400,
color: klightFontColor,
),
)
]),
]),
),
Positioned(
top: -190.0,
bottom: 0.0,
left: 20.0,
right: 20.0,
child:Container(
height: 80,
width:80,
child:Image.asset("assets/images/food1.png",),
)
),
]),
);
}),
I used the `singleChildscrollview()`, and `physics: ScrollPhysics(),` but still same error
just remove the shrinkWrap or set it to false and delete the SingleChildScrollView if you want the GridView to take All the space available wrap it in an Expanded Widget
I am new to flutter and I am making a shop app.
In the homescreen I have used grid view builder to display images of items. Now I want to add two text widgets at the bottom of each grid view item which shows the item name and price of the item.
This gridview builder is a child of a column widget. The column widget has two text widgets and gridview builder as its child.
GridView.builder(
padding: const EdgeInsets.all(10.0),
itemCount: loadedProducts.length,
itemBuilder: (ctx, i) => Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: secondaryColorlight,
borderRadius: BorderRadius.circular(defaultBorderRadius)),
child:
Image.asset(
loadedProducts[i].imageUrl,
height: 132,
),
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
)
This is how my homepage looks right now
This is how I want it to look
You can return Column from itemBuilder. You may also need to increase height from childAspectRatio
itemBuilder: (ctx, i) => Column(
children: [
Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: secondaryColorlight,
borderRadius: BorderRadius.circular(defaultBorderRadius)),
child: Image.asset(
loadedProducts[i].imageUrl,
height: 132,
),
),
// padding if needed
Text("your text"),
],
),
Also you can check GridTile widget.
More about layout in flutter
GridView.builder(
padding: const EdgeInsets.all(10.0),
itemCount: loadedProducts.length,
itemBuilder: (ctx, i) => Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: secondaryColorlight,
borderRadius: BorderRadius.circular(defaultBorderRadius)),
child:
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Flexible(
flex: 1,
fit: FlexFit.tight,
child: Container(
height: 190.0,
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child:Image.asset('images/image.png'),
),
),
),
SizedBox(height: 5.0),
Padding(
padding: const EdgeInsets.only(left: 10.0, bottom: 5.0, right: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Text('Price'),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
Text('Sometext'
maxLines: 1,
overflow: TextOverflow.ellipsis, ),
],
),
Text('title',
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
),
],
),
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
)
i'm trying to do this page
but what i get is this
this is my code
SingleChildScrollView(
child: Column(
children: [
Center(
child: Container(
margin: EdgeInsets.all(20),
width: 230,
height: 40,
child: ElevatedButton(
onPressed: () {
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(Color(0xff28CC61)),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
),
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Text("Add a book", style: TextStyle(
fontSize: 20
),),
),
),
),
),
Container(
child: Text("Explore between 10 books", style: TextStyle(
fontSize: 20
),),
),
Container(
//adding: EdgeInsets.all(12),
child: SingleChildScrollView(
child: GridView.builder(
shrinkWrap: true,
physics: BouncingScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 1,
crossAxisSpacing: 20,
crossAxisCount: 2,
mainAxisSpacing: 8),
itemCount: books.length,
itemBuilder: (BuildContext ctx, index) {
return Container(
width: 50,
height: 100,
child: Card(
color: Color(0xFFEDEDED),
child: Column(
children: [
Image.asset(books[index].image, height: 150
,
width: 150,fit: BoxFit.cover,),
],
),
),
);
}),
),
),
],
),
),
ignore the colors and styles i want how to do the page
i stucked on gridview and how to write text below the picture + How can I fix my code to do it? So each image has same size as others? i tried to see the grid view documentation and i could not find anything.
Change childAspectRatio : 1 to childAspectRatio:0.7. childaspectRatio defines the ratio between width and height of children. If you set it as 1 you will get a square shaped widget. More than 1 is horizontal rectangle and less than 1 gives vertical rectangle.
In my project i need to display a grid of products,2 in each row. For that I am using GridView.builder() as follows :
#override
Widget build(BuildContext context) {
return Column(
children: [
const Text('New Arrivals'),
const SizedBox(height: 10),
Expanded(
child: Consumer<HomeViewModel>(
builder: (context, model, child) {
if (model.state == ViewState.idle) {
if (model.products.isEmpty) {
return const Center(
child: CircularProgressIndicator(color: Colors.black),
);
}
return GridView.builder(
shrinkWrap: true,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
itemBuilder: (context, index) =>
ProductItem(product: model.products[index]),
itemCount: model.products.length,
);
}
return const Center(
child: CircularProgressIndicator(color: Colors.black),
);
},
),
),
],
);
}
However, this is giving an A RenderFlex overflowed by 49 pixels on the bottom. error on each item. The no. of pixels overflowed is different for different item.I have attached the screenshot for reference. What am I doing wrong and how do I fix it?
product_item.dart:
class ProductItem extends StatelessWidget {
const ProductItem({Key? key, required this.product}) : super(key: key);
final Product product;
#override
Widget build(BuildContext context) {
return Container(
width: 200,
color: Colors.white,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 200,
height: 150,
child: Image.network(product.imageUrl!),
),
const SizedBox(height: 13),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
product.category!,
softWrap: true,
style: const TextStyle(
fontSize: 10,
color: Colors.deepPurple,
height: 1.5,
fontWeight: FontWeight.w500,
),
),
),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
product.title!,
softWrap: true,
style: const TextStyle(
color: Colors.black54,
fontSize: 12,
height: 1.8,
fontWeight: FontWeight.w500,
),
),
),
const SizedBox(height: 10),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'\$ ${product.price!}',
style: const TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.w600,
height: 2.4,
),
),
Image.asset('assets/icons/cart_icon.png',
width: 40, height: 40),
],
),
)
],
),
);
}
}
the problem "should" lie within:
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text(
product.title!,
softWrap: true,
style: const TextStyle(
color: Colors.black54,
fontSize: 12,
height: 1.8,
fontWeight: FontWeight.w500,
),
),
),
try using: AutoSizeText instead of Text
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: AutoSizeText(
product.title!,
softWrap: true,
maxLines: 1,
style: const TextStyle(
color: Colors.black54,
fontSize: 12,
height: 1.8,
fontWeight: FontWeight.w500,
),
),
),
Default childAspectRatio is 1 on GridView. The issue arise because it is not fitting inside the square. Item's size is depending on screen width. And width is controlling the height,=> aspect ratio.
You can play with size of grid item using childAspectRatio:width/height. Alternative, you can follow #Maurizio Mancini's answer.
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 3 / 4,//this
),
I have used your code to reproduce the issue. If I understood your needs right, here is the fix:
The main problem is related to childAspectRatio.
return GridView.builder(
shrinkWrap: true,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 0.75,
),
itemBuilder: (context, index) =>
ProductItem(product: model.products[index]),
itemCount: model.products.length,
);
So you need to set the aspect ratio similar to this to fix the problem.
You can access the working source code through GitHub.