How to place the items 3 per row in Flutter - flutter

I have a list with 20 items in a list (dynamic not fixed). I want to display these items in a container with 3 or 4 items per row.
At present I am getting the attached output.
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(itemList.length,
(index) {
return Wrap(
children: <Widget>[
Container(
//height:140,
child: SizedBox(
width: 100.0,
height: 50.0,
child: Card(
color: Colors.white,
semanticContainer: true,
clipBehavior:
Clip.antiAliasWithSaveLayer,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10.0),
),
elevation: 5,
margin: EdgeInsets.all(10),
child: Center(
child: Text(
(itemList.length[index]
.toUpperCase()),
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.bold,
fontSize: 15.0,
),
),
),
),
)),
],
);
}),
),

You can achieve this using a widget called GridView.builder. Check the code below for how to use a gridview widget:
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
// number of items per row
crossAxisCount: 3,
// vertical spacing between the items
mainAxisSpacing: 10,
// horizontal spacing between the items
crossAxisSpacing: 10,
),
// number of items in your list
itemCount: 20
),
To read more on the GridView widget, check the link below:
GridView Widget in Flutter
I hope this helps.

Use a GridView.
GridView.builder(
scrollDirection: Axis.vertical,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
)

Using a GridView works for me.
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4 //How many items do you want to show,
mainAxisSpacing: 10 //Space between the lines,
crossAxisSpacing: 10 //Space between the items,
),

Related

GridView grid delegate display grids the same on all devices

I used gridView.builder. To set the size of the grid, I use MediaQuery, but for some reason the gridView is displayed differently on different devices, using which parameter in gridDelegate: can I fix this?
my gridView code:
Widget buildCatalog(List<Product> product) => CustomScrollView(
controller: sController,
slivers: [
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
// mainAxisExtent: ,
maxCrossAxisExtent: 300,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.3),
crossAxisSpacing: 10,
mainAxisSpacing: 10),
delegate: SliverChildBuilderDelegate(childCount: product.length,
(BuildContext context, int index) {
return GestureDetector(
onTap: () {},
child: Container(
padding: const EdgeInsets.only(left: 2, right: 2, top: 5),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8)),
child: Column(
children: <Widget>[
InkWell(
child: Container(
margin: const EdgeInsets.only(top: 5),
child: Image.network(),
),
),
const SizedBox(
height: 10,
),
Text(),
// Spacer(),
const SizedBox(height: 8),
Text(),
const SizedBox(height: 5),
buildButton(index, productItem.id),
],
),
),
);
}),
),
]
);
This is my grid on big displays:
and this on small displays:
The solution was flutter_screenutil package

How to plot same space between MainAxisAlignment.spaceBetween and MainAxisAlignment.start?

Please refer to my code and Screen Shot below
Top two rows are build based on MainAxisAlignment.spaceBetween widget and a bottom row is on MainAxisAlignment.spaceBetween, respectively.
As you can see in Screen Shot,MainAxisAlignment.spaceBetween have no spaces like spacebetween, and I understood this is default behaviour of MainAxisAlignment.
However, I want keep same spaces between the items in 5 items, even if it consists of less than 5 items(like two items shown in Screen shot).
Is there any good ideas to implement this ?
thanks for your helpful advise.
final List<String> _icon = [
"lock.png",
"cheer.png",
"map.png",
"stake.png",
"sushi.png",
"lock.png",
"cheer.png",
"map.png",
"stake.png",
"sushi.png",
"cheer.png",
"map.png"
];
var iconChunks = _icon.slices(5).toList();
Column(
children: iconChunks.map((e) => Padding(
padding: const EdgeInsets.only(bottom: 10.0),
child: Row(
mainAxisAlignment: e.length ==5 ? MainAxisAlignment.spaceBetween :MainAxisAlignment.start,
children: e.map((s) => selectIcon(id: 1, iconPass: s)
).toList(),
),
))
.toList()
),
Have you tried using GridViewBuilder? Maybe this will help.
GridView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
itemCount: _icon.length,
itemBuilder: ((context, index) => selectIcon(id: 1, iconPass:
_icon[index])),
),
You can easily maintain same height and weight by Gridview. Column Spacebetween and start are totally different concept.As you are don't know about list, it may be increase or decrease better you should have to use Gridview.
return Container(
// padding: const EdgeInsets.all(0.0),
child: GridView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: lengthoflist,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.4),
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
),
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
Category category = snapshot.data[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
child: Image.network(
category.image,
fit: BoxFit.cover,
),
decoration: BoxDecoration(
border: Border.all(width: 1.0),
),
),
Padding(
padding: const EdgeInsets.only(
top: 8.0,
),
child: Text(
category.name,
textAlign: TextAlign.center,
),
)
],
);
},
),
);

How to solve Flutter bottom overflow error

I have tried to create Listview.builder with help of API(for displaying API product). but i got error in bottom pixel. i tried many ways to solve this problem. but couldn't find anything,
how can i solve this problems by editing code... And what is the main reason for this error
code is here
Container(
height: 650,
child: FutureBuilder(
future: _getProduct(),
builder: (context, snapshot) {
if (snapshot.data == null) {
return const Center(child: Text("Loading"));
} else {
return GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
itemCount: snapshot.data?.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(right: 10),
child: Container(
width: 130,
height: 485,
decoration: BoxDecoration(
color: Colors.white,
borderRadius:
BorderRadius.circular(10)),
child: Container(
height: 240,
child: Column(
children: [
Padding(
padding: EdgeInsets.all(5),
child: Image.network(
snapshot.data![index].image)),
Padding(
padding: const EdgeInsets.all(10),
child: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Expanded(
child: Text(
snapshot.data![index].name,
overflow: TextOverflow.fade,
maxLines: 2,
style: const TextStyle(
fontSize: 15,
fontWeight:
FontWeight.w700),
)),
Text(
snapshot.data![index].price)
],
),
)
],
),
),
),
);
},
);
}
}),
)
Issue with this
GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
Needed to add Shrinkwrap & Add the Ratio
shrinkwrap: true,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 0.8,
),
I am a beginner in flutter,
I changed to your code and working ok,
need a single line to be added to your code...
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 1 / 1.5,//<- add this one (it will increase height of your card or container)
crossAxisCount: 2),

Flutter: FlexLayoutManager similar to the one in native android

So I'm trying to implement a flex listview similar to the google FlexLayoutManager to the horizontal axis with wrap, you can see an example in the wrap section
https://github.com/google/flexbox-layout/raw/main/assets/flex-wrap.gif
here is my code:
ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categories.length,
padding: EdgeInsetsDirectional.only(start: 16, end: 12),
itemBuilder: (context, index) {
return InkWell(
onTap: (){
},
child: Container(
height: 24,
alignment: Alignment.center,
child: Text(
categories[index].name,
),
),
);
},
)
what I have to add to my listview to make the items wrap and move to the next row if they exceeded the screen width?
Not tested, but as I indicated in my comment, I'd use something like:
Wrap(
children: [
for (final c in categories)
InkWell(child: Text(c.name)),
]);
adding of course all your parameters, and the extra container.
As an alternative, you can use a GridView.builder instead of ListView.builder:
Creates a scrollable, 2D array of widgets that are created on demand.
result:
I have made my window very small and the children still wrap:
With the window maximized:
code:
GridView.builder(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
childAspectRatio: 3 / 2,
crossAxisSpacing: 20,
mainAxisSpacing: 20),
itemCount: _categories.length,
padding: EdgeInsetsDirectional.only(start: 16, end: 12),
itemBuilder: (context, index) {
return InkWell(
onTap: () {},
child: Container(
height: 24,
alignment: Alignment.center,
child: Text(
categories[index].name,
),
),
);
},
)

How to align text and image in a SliverGrid in Flutter?

I am using the SliverGrid feature to build my gridView. I trying to have the text placed below the image but the text isn't aligning with the image and its showing a Bottom Overflowed error. This is the code:
SliverPadding(
padding: const EdgeInsets.only(left: 8, right: 8),
sliver: SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 20,
mainAxisSpacing: 20,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int i) {
return GestureDetector(
onTap: () {},
child: Column(
children: <Widget>[
GridTile(
child: Image.network(
'https://images.unsplash.com/photo-1562176566-73c303ac1617?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80',
fit: BoxFit.cover,
),
),
Text(
'Sammy the Pup',
style: khomeStyle.copyWith(
color: kOrange, fontSize: 14),
),
],
),
);
},
childCount: 200,
),
),
),
And this is what the gridview looks like(Output of the above):
And this is what I want to achieve:
The height of GridView is determined by the AspectRatio
SliverGridDelegateWithFixedCrossAxisCount(
mainAxisSpacing: 5.0,
crossAxisSpacing: 5.0,
crossAxisCount: 2,
childAspectRatio: 1 / 1,<---
),
As the AspectRatio gets smaller the height gets larger and as the ratio gets larger the heights gets smaller