All children of this widget must have a key(edit:) - flutter

enter image description hereI am trying to make a ReorderableListView, which needs a key. I put it, however it returns the error "All children of this widget must have a key". Can anyone help me? (I've seen similar problems here but I still couldn't solve it)
ReorderableListView(
onReorder: _onReorder,
scrollDirection: Axis.vertical,
padding: const EdgeInsets.symmetric(vertical: 8),
children: <Widget>[
ListView.builder(
itemCount: dias.length,
itemBuilder: (context, int index) {
return Padding(
key: ValueKey(dias[index]),
padding: EdgeInsets.all(0),
child: _cartaodia(context, index),
);
}
),
],
)
edit: I saw some examples that used the key of this form, however the index it does not recognize the index as shown in the image

Your listViewBuilder also require Key.
ListView.builder(
key: Key(dias.length.toString()), // added line
itemCount: dias.length,
Update:
ConstrainedBox(// added widget
constraints:
BoxConstraints(maxHeight: MediaQuery.of(context).size.height),
key: Key("Const"),
child: ListView.builder(
// add the value key inside the list view instead
key: ValueKey("list"),
itemCount: 50,
// shrinkWrap: true,
itemBuilder: (context, int index) {
return Padding(
padding: EdgeInsets.all(0),
child: Text("hello"),
);
}),
),

Try adding the ValueKey inside the ListView.builder widget instead.
Like this:
ReorderableListView(
onReorder: _onReorder,
scrollDirection: Axis.vertical,
padding: const EdgeInsets.symmetric(vertical: 8),
children: <Widget>[
ListView.builder(
// add the value key inside the list view instead
key: ValueKey(dias[index]),
itemCount: dias.length,
itemBuilder: (context, int index) {
return Padding(
padding: EdgeInsets.all(0),
child: _cartaodia(context, index),
);
}
),
],
)

Related

flutter GridView.builder won't let rest of screen scroll

I have GridView.builder middle of my screen but it does not let my screen to scroll! I must find some white space in screen in order to be able to scroll rest of my screen.
Here is how my screen structure looks like:
Widget build(BuildContext context) {
return Scaffold(
appBar: const TopBarFile(),
drawer: const DrawerFile(),
body: SafeArea(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: FutureBuilder(
future: myCards,
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// some widgets...
const SizedBox(height: 15),
// here middle of screen is GridView
SizedBox(
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
shrinkWrap: true,
itemCount: snapshot.data['cards'].length,
itemBuilder: (BuildContext context, int index) {
return InkWell(...);
}
)
),
const SizedBox(height: 15),
// some more widgets...
]
);
} else {...}
return container();
}
),
),
),
),
),
}
Note: this grid view only has 6 items so I don't need it to be scrollable actually I just use it for design purpose but its causing scrolling issue, so I just need to be able to scroll my page even if I'm touching on top of this grid view items.
Any suggestions?
you can define a physics property with NeverScrollableScrollPhysics() value inside GridView, this will solve the issue. Always use physics property When you have nested scrollable widget.
You can give physics: NeverScrollableScrollPhysics() to GridView() or use Wrap() widget instead of GridView().
Use physics and shrinkWrap property as below:
SizedBox(
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: snapshot.data['cards'].length,
itemBuilder: (BuildContext context, int index) {
return InkWell(...);
}
)
),

How to create horizontal Listview in listview builder flutter

I am using an API to build a movies application, I had a problem with making theListView to be from left to right instead of up and dowm.I am trying to create a horizontal list view but it displayed not as expected. You can see how it looks in the Image bellow. It works with me usually but it my first time to do that inside a listview builder. How to fix that?
Note: I want the full screen to be vertical and this part only horizontal.
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child:
FutureBuilder(
future: getData(),
builder: (BuildContext context,AsyncSnapshot snapshot){
if(snapshot.data == null){
return Container(
child: Center(
child:CircularProgressIndicator() ,),);
}
else{
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context,int i){
if(snapshot.data==null){
return Center(
child: CircularProgressIndicator(),
);
}
else{
return Container(
height: 250,
child: Card(
child: ListView(
scrollDirection: Axis.horizontal,
children: [
Image(image: NetworkImage(snapshot.data[i].poster))
],
),
),
);
}}
);
}
}
,),
),
);
}
}
Image
You can use scrollDirection: Axis.horizontal,
inside the Listview.Builder to make it scroll horizontally and add a width for the container that's being returned.
Try below code hope its helpful to you . declare your ListView.builder() like below refer Listview here
Container(
width: double.infinity,
height: 180,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: 10,
itemBuilder: (BuildContext context, int i) {
return Container(
height: 50,
child: Card(
child: Image.network(
'https://tech.pelmorex.com/wp-content/uploads/2020/10/flutter.png',
),
),
);
},
),
),
Your result screen->

Issues with GridView for the following UI

I am trying to construct the following UI, but having issues with that. More specifically I tried different ways of doing this with GridView, but had no luck since I was not able to switch from 2 to 1 for crossAxisCount, because after showing the favorite cakes I need to "come back" to "normal" and show one block on one line for "Similar Products". Here is what I tried:
body: new LayoutBuilder(
builder: (context, constraint) {
return Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0, 8.0, 0),
child: new GridView(
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: constraint.maxWidth / constraint.maxHeight,
),
children: <Widget>[
// those widgets here will be created dynamically at the end
// manually created a few just for illustration
new MyFavoriteWidget(),
new MyFavoriteWidget(),
new MyFavoriteWidget(),
new MyFavoriteWidget(),
new MyFavoriteWidget(),
new MyFavoriteWidget(),
new MyFavoriteWidget(),
new MyFavoriteWidget(),
new Container(
child: Text("Similar Products"),
),
// same for those widgets
new SimilarProductWidget(),
new SimilarProductWidget(),
new SimilarProductWidget(),
new SimilarProductWidget(),
],
),
);
},
),
But this renders just 2 columns, which is what I want for the top part, but after the list of MyFavoriteWidget() I need to switch to normal layout and have one block on one line. And if I take this part out of the GridView it won't be visible. I feel like GridView is still the best way of implementing this but was not able to find a way around it. Even a skeleton code to get started or a hint how to overcome this issue will be much helpful.
I offer you try this code. For top list use GridView.count and for bottom list use ListView.builder. I give you a simple example to understand it. Run code below and see the result.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Your heading'),
),
body: SafeArea(
child: ListView(
shrinkWrap: true,
physics: ScrollPhysics(),
children: [
GridView.count(
crossAxisCount: 2,
scrollDirection: Axis.vertical,
physics: ScrollPhysics(),
shrinkWrap: true,
children: List.generate(
6,
(index) => Container(
margin: EdgeInsets.all(10),
width: 50,
height: 50,
color: Colors.yellow,
),
),
),
ListView.builder(
physics: ScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: 10,
itemBuilder: (BuildContext context, int index) {
return Card(
color: Colors.red,
child: Container(
height: 70,
margin: EdgeInsets.all(30),
width: double.infinity,
),
);
},
),
],
)));
}

Flutter - How to list out forEach() value in ListView builder?

Hi I am trying to list data from JSON to Listview Builder . But Flutter is giving me this error: Column's children must not contain any null values, but a null value was found at index 0
I tried to map each one like this inside the listview
alo[Index]['rewards'].forEach((k, v) {
Text(v['name']);
}),
Here is my full code:
shrinkWrap: true,
itemCount: alo.length,
itemBuilder: (BuildContext ctxt, int Index) {
return Card(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: <Widget>[
alo[Index]['rewards'].forEach((k, v) {
Text(v['name']);
}),
],
),
));
});
Is there any solution to this? Thank you!
The thing is forEach() doesn't return anything, you could use map() instead, like this:
children: alo[Index]['rewards'].values.map<Widget>((v) => Text(v['name'])).toList()
If you want to add more widgets, you could do something like this:
Column(
children: <Widget>[
Column(
children: alo[Index]['rewards']
.values
.map<Widget>((v) => Text(v['name']))
.toList(),
),
Text('Other widget'),
],
)
You have two options, if you don't have any rewards then you can
a) Leave an empty card
shrinkWrap: true,
itemCount: alo.length,
itemBuilder: (BuildContext ctxt, int Index) {
return Card(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: <Widget>[
alo[Index]['rewards']!=null?
alo[Index]['rewards'].forEach((k, v) {
return Text(v['name']);
}):SizedBox()
],
),
));
});
or
b) don't render any card
shrinkWrap: true,
itemCount: alo.length,
itemBuilder: (BuildContext ctxt, int Index) {
return alo[Index]['rewards']!=null?Card(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: <Widget>[
alo[Index]['rewards'].forEach((k, v) {
return Text(v['name']);
}),
],
),
)):SizedBox();
});

How to iterate through widgets with different Views

Am beginner in flutter. I have four widgets with different view i.e. BarChart, LineChart, StackedBarChart and CircularChart. Then i created a List
final List<Widget> widgetList = <Widget>[
BarChartWidget(), LineChartWidget(), StackedBarChartWidget(), CircularChartWidget(),];
How can i iterate through List of this widgets in ListView
body: new ListView.separated(
itemCount: entries.length,
padding: EdgeInsets.all(8.0),
itemBuilder: (BuildContext context, int index) {
return Container(
height: 150,
color: Colors.amber[colorCodes[index]],
child: new widgetList[index],
);
},
separatorBuilder: (BuildContext context, int index) => const Divider(),
)
);
You were almost there. The issue is:
child: new widgetList[index],
That's not a valid syntax. You cannot "new" widgetList, as it is a variable.
Just do:
child: widgetList[index],
Here's the final syntax:
new ListView.separated(
itemCount: entries.length,
padding: EdgeInsets.all(8.0),
itemBuilder: (BuildContext context, int index) {
return Container(
height: 150,
color: Colors.amber[colorCodes[index]],
child: widgetList[index],
);
},
separatorBuilder: (BuildContext context, int index) => const Divider(),
);