I am trying to show listview.builder inside simpledialog but it doesn't work
here is my code:
onTap: () {
return showDialog(
builder: (BuildContext context) {
return SimpleDialog(
title: Text('names'),
children: [
ListView.builder(
itemCount: names.length,
itemBuilder: ((context, index) {
return SimpleDialogOption(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(names[index].name),
);
}))
],
);
},
context: context);
},
change this line:
names[index].name
to this:
names[index]name
It won't work if you use the period between the values. But you should get an error for that.
Related
I am working on a statefulWidget and my purpose is to make sure that the next button is not clickable until an option (in this language is selected). However it doesn't seem to work, I also added Yaesin's(Someone who answered) answer to the code
ListView.builder(
itemCount: histoires.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(
histoires[index].title,
style: TextStyle(color: Colors.pink),
),
trailing: IconButton(
icon: Icon(Icons.play_arrow),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (context, setState) =>
AlertDialog(
content: Column(children: [
InkWell(
onTap: () {
_handleTap;
},
child: ListTile(
trailing: Icon(Icons
.flag_circle_rounded),
title: Text(
"French",
style: TextStyle(
color: Colors
.blueGrey),
))),
_active
? InkWell(
onTap: () {},
child: Image.asset(
"assets/nextactive.png",
height: height * 0.2,
width: width * 0.4),
)
: Image.asset(
"assets/nextinactive.png",
height: height * 0,
width: width * 0)
]),
));
});
}));
}),
To update dialog UI, you can use StatefulBuilder's setState
return StatefulBuilder(
builder: (context, setState) =>
AlertDialog(
content: Column(children: [
While using separate method, pass the StatefulBuilder's setState to the function. For your case, it will be
onPressed: () async {
await showDialog(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (context, setStateSB) => AlertDialog(
content: Column(children: [
InkWell(
onTap: () {
_handleTap(setStateSB);
},
child: ListTile(
Also make sure to receive this setStateSB(renamed to avoid confusion with state's setState).
_handleTap(setStateSB){ ....
More about using StatefulBuilder
Since your in a Dialog, for setState to work, you need to wrap it with a StatefulBuilder.
You haven't included your full code, so I'm using this example taken from the docs:
await showDialog<void>(
context: context,
builder: (BuildContext context) {
int? selectedRadio = 0;
return AlertDialog(
content: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Column(
mainAxisSize: MainAxisSize.min,
children: List<Widget>.generate(4, (int index) {
return Radio<int>(
value: index,
groupValue: selectedRadio,
onChanged: (int? value) {
setState(() => selectedRadio = value);
},
);
}),
);
},
),
);
},
);
See also
A YouTube video by the Flutter team explaining StatefulBuilder
I have to use showModalBottomSheet for displaying list of menu item. But I am unable to dynamically set the height of the bottomsheet. Please help me to solve this issue. Thankyou.
This is how you can dynamically change the bottomsheet height based on the length of the list in the bottom sheet. But be aware of that you need to use statefulbuilder in the showModalBottomSheet to be able to setState the list.
List<int> myList = [1,2,3,4,5,6];
#override
Widget build(BuildContext context) {
return Center(
child: ElevatedButton(
child: const Text('showModalBottomSheet'),
onPressed: () {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (context, _setState){
return Container(
height: myList.length * 100,
color: Colors.amber,
child: ListView.builder(
itemCount: myList.length,
itemBuilder: (BuildContext ctxt, int index) {
return Row(
children: [
Text(myList[index].toString()),
TextButton(
onPressed: () {
_setState((){
myList = myList.where((value) => value != myList[index]).toList();
});
},
child: Text("delete"),
)
]);
}
)
);
}
);
},
);
},
),
);
}
body: ListView.builder(
// i do not know where should i put the sizedBox to make these image has space to separate
itemCount: a.length,
itemBuilder: (context, index) {
return GestureDetector(
child: ListTile(title: (a[index][0])),
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => a[index][1]));
},
);
},
),
Use the ListView.separated, it has a separatorBuilder property that will help you to add the SizedBox, here the example:
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.separated(
itemCount: 10, // add the length of the array of items, for example data.length
itemBuilder: (BuildContext context, int index) => Text('Hola $index'), // here build the cards body
separatorBuilder: (BuildContext context, int index) => const SizedBox(height: 15), // here the SizedBoxed
),
);
}
I have wrapped ListView.builder inside Visible widget, and the button for its visible property is in a ListTile widget with variable _currencyVisible.
The widget Visible works 2 times i.e. false/hidden(default), then changes to visible when clicked, and again hides on the second click, but it doesn't work after that. Printing on console _currencyVisible shows correct data.
Here's my code:
menuItems(BuildContext context) {
bool _currencyVisible = false;
return StatefulBuilder(
builder: (BuildContext context, void Function(void Function()) setState) {
return ListView(
children: [
ListTile(
title: FutureBuilder<dynamic>(
future: getUserCurrencySymbol(),
builder:(BuildContext context, AsyncSnapshot<dynamic> snapshot) {
return Text("Currency " + snapshot.data.toString());
}),
trailing: IconButton(
icon: Icon(Icons.refresh),
onPressed: () { setState(() { _currencyVisible = !_currencyVisible; }); },
),
),
Visibility(
visible: _currencyVisible,
child: ListView.builder(
shrinkWrap: true,
itemCount:
currency.allCurrenciesList.length,
itemBuilder: (context, index) {
for (Currency c in currency.allCurrenciesList) {
currency.allCurrenciesList.removeAt(0);
return Card(
child: ListTile(
title: Text(c.country),
subtitle: Text(c.shortCurrency),
trailing: Text(c.symbol),
onTap: () {
saveUserCurrency(c.country, context);
},
),
);
}
return Text("Not Null");
},
),
),
],
);
},
);
}
You are removing all of the data from your currency list. The widget is showing correctly, but there is no data to display.
Remove this line
currency.allCurrenciesList.removeAt(0);
Don't loop through the currencies in itemBuilder. Use index instead.
Visibility(
visible: _currencyVisible,
child: ListView.builder(
shrinkWrap: true,
itemCount: currency.allCurrenciesList.length,
itemBuilder: (context, index) {
final c = currency.allCurrenciesList[index];
return Card(
child: ListTile(
title: Text(.country),
subtitle: Text(c.shortCurrency),
trailing: Text(c.symbol),
onTap: () {
saveUserCurrency(c.country, context);
},
);
}
return Text("Not Null");
),
),
I am trying to build a search list, the list is working fine but if the result is empty i need to show no data. I tried the following code but the widget holds for a second and then disappear
FutureBuilder(
future: getSearchedProducts(widget.searchString),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return Center(
child: Container(
child: Text('No Data Found.'),
),
);
} else {
return ListView.builder(
shrinkWrap: true,
itemCount: searchResult.length,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: Image.network(searchResult[index].proThumbnail),
title: Text(searchResult[index].proName),
onTap: () {
print(searchResult[index].proName);
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ProductPage(prodid: searchResult[index].proId);
}));
},
),
);
});
}
})
Can anyone help me with this.
Thank you in advance.
I just write the code as below and it works.
FutureBuilder(
future: getSearchedProducts(widget.searchString),
builder: (BuildContext context, AsyncSnapshot snapshot) {
print('length of list ${searchResult.length}');
if (searchResult.length==0) {
return Center(
child: Text('No data'),
);
}
else if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
else {
return ListView.builder(
shrinkWrap: true,
itemCount: searchResult.length,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: Image.network(searchResult[index].proThumbnail),
title: Text(searchResult[index].proName),
onTap: () {
print(searchResult[index].proName);
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ProductPage(prodid: searchResult[index].proId);
}));
},
),
);
});
}
}),
In your Code in Else part before - return ListView.builder- add the following code.
...
else {
if (searchResult.length == 0)
{
return Center(child: const Text('No Date'));
}
return ListView.builder .....