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,
),
),
);
},
)
Related
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 make flutter ListView.builder without a specific height(dynamic or not declare the height)
I want to make a list of item, and then when the item going to full height it will wrapped
When i run this code, it returns error because it need height and width
I want to make the list of item like this
Wrap(
spacing: 12,
runSpacing: 10,
children: [
ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: movieDetail['genre'].length,
itemBuilder: (context, index) {
return ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Container(
color: darkGrayColor,
child: Padding(
padding: EdgeInsets.symmetric(
vertical: 4, horizontal: 12),
child: Text('Testing', style: secondaryInfoText),
),
),
);
},
),
],
),
Use GridView.builder
GridView.builder(
scrollDirection: Axis.horizontal,
itemCount: movieDetail['genre'].length,
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 1),
itemBuilder: (context, index) {
...
}
In the following code, all items are displayed on a separate line i.e. each item spans over the entire row. How can I change the code so that multiple items can appear on the same line?
Thanks in Advance :)
Expanded(
child: SizedBox(
child: new ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: filterStatus == false
? allDeals.length
: filteredDeals.length,
itemBuilder: (BuildContext ctx, int index) {
return Container(
margin: EdgeInsets.only(top: 20.0),
child: ListTile(...)
);
}
),
),
),
If you want to do something like this:
You can use the GridView.builder.
Here is the code that built the example from the screenshot.
GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 100, // the size of item
crossAxisSpacing: 10, // margin of 10px top and bottom
mainAxisSpacing: 10, // margin of 10px left and right
// the spacing is not applicable on the GridView margins.
),
itemCount: 30,
itemBuilder: (_, index) {
return Container(
color: Colors.blue,
child: Center(
child: Text(
'Item $index',
),
),
);
},
),
I was tryiing to use double row in a single Listview which should scroll together in a single ListView Widget when i added double rows in a column inside the listview wigdget I combine both rows instead of creating a new row. Image is attached.Marked Section
You can use GridView instead, Here is the sample code
Container(
height: 150,
width: MediaQuery.of(context).size.width,
child: GridView.builder(
itemCount: 20,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 1,
mainAxisSpacing: 1,
childAspectRatio: 1,
),
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Container(
color: Colors.red,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.ac_unit),
Text('data $index'),
],
),
);
},
),
);
Below is my code, I want to add some extra space of height 50, which comes at the end of list item. because when my second child of stack appears it nearly overlaps the last item of list view. I've tried wrapping ListView.builder with column and added a container at last but destroyed my whole structure. for this scenario I've to wrap the column into Single scrollable which pushed stack 2nd widget to be at the end of ListItem.(But I don't want Stack 2nd object to be scrollable).
As you can see I'm not able to click on HotDog.
body: Stack(
children: <Widget>[
ListView.builder(
itemCount: itemData.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context,int index){
return Text(data[index].name);
}
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.cyan
),
padding: EdgeInsets.all(10),
height: 60,
),
)
],
),
How about you add empty last item like below code?
ListView.builder(
itemCount: itemData.length + 1,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context,int index){
if (index == item.Data.length) {
return SizedBox(height: 50);
} else {
return Text(data[index].name);
}
}
),
ListViewBuilder should be wrap inside Expanded widget which will take fullscreen
and give container bottom width as per need.
Example:
var itemData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
Stack(
children: <Widget>[
Column(
children: <Widget>[
Expanded(
child: Container(
margin: EdgeInsets.only(bottom: 20),
child: ListView.builder(
itemCount: itemData.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 80,
child: Text("Text :" + index.toString()));
}),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.cyan),
padding: EdgeInsets.all(10),
height: 60,
),
),
)
],
),
],
),
Output:
This can be easily done by adding bottom padding in listview.builder
Expanded(
child: ListView.builder(
padding: EdgeInsets.only(bottom: 100), //Increase this as per your requirment
itemCount: 5,
itemBuilder: (cxt , idx) {
return YourWidget();
}
Since you're listview.builder is inside a stack, you simply use the Positioned widget for this. Simply wrap your listview with Positioned like below:
Positioned(
bottom:50, //adjust this since this is the padding inside the stack
child:Container(
width:MediaQuery.of(context).size.width //width of the whole phone
child: ListView.builder(
itemCount: itemData.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context,int index){
return Text(data[index].name);
}
),
),
),
To ensure your Container stays at the bottom wrap it with a positioned widget and set the bottom property to 0:
Positioned(
bottom:0, //adjust this since this is the padding inside the stack
child:Container(),
),
Here is a one minute clip showing how to use the Positioned widget: https://www.youtube.com/watch?v=EgtPleVwxBQ
There is no specific way to do it by default you have to do it manually with own logic
ListView.builder(
itemCount: itemData.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context,int index){
if(index == itemData.length - 1 )
return Padding(
padding: EdgeInsets.only(bottom : 50),
child : Text(data[index].name)
);
return Text(data[index].name);
}),