AlertDialog with a CheckboxListTile in flutter - flutter

I'm having some problems when I use a CheckboxListTile inside a AlertDialog. The problem is that when I try to check, the box doesn't work correctly. This is my code:
import 'package:flutter/material.dart';
void main() {
runApp(PadelApp());
}
class PadelApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false, //esto es para quitar el cartelito de debug
title: 'Test',
theme: ThemeData( primarySwatch: Colors.blue),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget{
//#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>{
var _formkey = GlobalKey<FormState>();
var _lstgrupos = ['Group 1', 'Group 2'];
List<String> _SelectedGroupsItems = [];
String _SelectedGroups = 'Groups';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Test')),
body: Form(
key: _formkey,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: ListView(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: ListTile(
title: Text(_SelectedGroups),
onTap: () => showDialog(
context: context,
barrierDismissible: true,
builder: (context) {
return AlertDialog(
title: Text("Choose a group"),
content: SingleChildScrollView(
child: Container(
width: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.min,
children: _lstgrupos.map((lst) => CheckboxListTile(
title: Text(lst),
value:_SelectedGroupsItems.contains(lst),
onChanged: (value) {
setState(() {
if (value!) {
if (!_SelectedGroupsItems.contains(lst)) {
_SelectedGroupsItems.add(lst);
}
} else {
if (_SelectedGroupsItems.contains(lst)) {
_SelectedGroupsItems.add(lst);
}
}
});
},
)).toList(),
),
),
),
actions: <Widget>[
TextButton(
child: Text('Cerrar'),
onPressed: ()=> Navigator.of(context).pop(),
)
]
);
}
),
),
),
],
),
],
),
),
),
);
}
}
I have tried to modify in several ways but I realize that the problem is in "value" variable (in onChanged: (value)). This variable is always true or always false but doesn't change.

You need surround your AlertDialog with StatefullBuilder
Otherwise the setState does not rebuild the dialog
Like this :
StatefulBuilder(
builder: (context, setState) {
return AlertDialog(...)
})

Related

Bad state: Cannot emit new states after calling close

I'm using flutter_form_bloc (https://pub.dev/packages/flutter_form_bloc) and I created two classes, the first is the login page:
class LoginScreen extends StatelessWidget {
const LoginScreen({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter - Parse Server',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: FutureBuilder<bool>(
future: hasUserLogged(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
return SafeArea(
child: Scaffold(
body: Center(
child: Container(
width: 100,
height: 100,
child: CircularProgressIndicator()),
),
),
);
default:
if (snapshot.hasData && snapshot.data!) {
return UserPage();
} else {
return LoginPage();
}
}
}),
);
}
}
class LoginPage extends StatefulWidget {
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final controllerUsername = TextEditingController();
final controllerPassword = TextEditingController();
final controllerConfirmPassword = TextEditingController();
bool isLoggedIn = false;
#override
Widget build(BuildContext context) {
return SafeArea(
child: SafeArea(
child: Scaffold(
body: SingleChildScrollView(
...
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Don\'t have an Account? ',
overflow: TextOverflow.ellipsis,
),
new InkWell(
child: new Text(
'Sign Up',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
onTap: () => Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (_) =>
const listRegistrationScreen2()))),
],
),
),
);
}
class UserPage extends StatelessWidget {
...
}
And the second is list registration:
class listRegistrationScreen2 extends StatelessWidget {
const listRegistrationScreen2({super.key});
#override
Widget build(BuildContext context) {
return _listRegistrationScreen();
}
}
class _listRegistrationScreen extends StatefulWidget {
#override
__listRegistrationScreen createState() => __listRegistrationScreen();
}
class __listRegistrationScreen extends State<_listRegistrationScreen> {
static var flag = false;
...
#override
void initState() {
formBloc = null;
super.initState();
}
#override
void dispose() {
formBloc = null;
super.dispose();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.black,
),
centerTitle: true,
actions: [
IconButton(
onPressed: () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (_) => const LoginScreen()));
},
icon: Icon(Icons.arrow_back))
],
),
body: BlocProvider(
create: (context) => ConditionalFieldsForm(),
child: Builder(
builder: (context) {
formBloc = BlocProvider.of<ConditionalFieldsForm>(context);
return Theme(
data: Theme.of(context).copyWith(
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
),
),
),
child: SafeArea(
child: Scaffold(
body: FormBlocListener<ConditionalFieldsForm, String,
String>(
onSubmitting: {
...
},
onSubmissionFailed: (context, state) {
LoadingDialog.hide(context);
},
onSuccess: (context, state) {
LoadingDialog.hide(context);
},
onFailure: (context, state) {
LoadingDialog.hide(context);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(state.failureResponse!)));
},
child: SingleChildScrollView(
physics: const ClampingScrollPhysics(),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
...
),
ElevatedButton(
onPressed: formBloc.submit,
child: Text('SUBMIT'),
),
],
),
),
),
),
),
),
);
},
),
)),
);
}
}
class LoadingDialog extends StatelessWidget {
...
}
class ConditionalFieldsForm extends FormBloc<String, String> {
static final roles = SelectFieldBloc(
validators: [FieldBlocValidators.required],
items: ['Trainee', 'Employer', 'Department'],
);
static final TraineeEmail = TextFieldBloc(
validators: [FieldBlocValidators.required, FieldBlocValidators.email],
);
...
ConditionalFieldsForm() {
addFieldBlocs(
fieldBlocs: [
roles,
],
);
...
#override
Future<void> close() {
TraineeEmail.close();
TraineePassword.close();
TraineeConfirmPassword.close();
TraineeDOB.close();
TraineePhoneNumber.close();
TraineeSkills.close();
TraineeNationality.close();
TraineeAddress.close();
TraineeCurrentInstituation.close();
TraineeMajor.close();
TraineeName.close();
TraineeGender.close();
EmployerPhoneNumber.close();
EmployerWebsite.close();
EmployerPassword.close();
EmployerEmail.close();
EmployerAddressID.close();
EmployerDescription.close();
EmployerName.close();
DepartmentPhoneNumber.close();
DepartmentPassword.close();
DepartmentEmail.close();
DepartmentAddressID.close();
DepartmentCategory.close();
DepartmentName.close();
roles.close();
terms.close();
traineeRegistred.close();
employerRegistred.close();
return super.close();
}
#override
onSubmitting() async {
}
}
The problem is when I navigate from login to list registration page then back to login page and try to back again to list registration page I got this error:
error message screen
I tried to use dispose and change login screen from state less to state full but that didn't work with me.

Alert dialogue not displaying even with show dialogue

I changed it to stateful and used return dialogue but still nothing.
void main() {
runApp(
MyApp(),
);
}
class MyApp extends StatefulWidget {
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
createAlertDialogue(BuildContext context) {
TextEditingController customeController = TextEditingController();
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text(" Your NAme"),
content: TextField(
controller: customeController,
),
actions: <Widget>[
MaterialButton(
elevation: 5.0,
child: Text('submit'),
onPressed: () {},
)
],
);
});
}
Widget _buildForgotPasswordBtn(BuildContext ctx) {
return Container(
alignment: Alignment.centerRight,
child: TextButton(
onPressed: () {
setState(() {
createAlertDialogue(ctx);
});
},
child: Text(
'forgot password',
style: kLabelStyle,
),
),
);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Color.fromARGB(206, 5, 42, 146),
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_buildForgotPasswordBtn(context),
],
),
),
),
);
}
}
I used setState and even put ctx in createalertdialogue because it didn't work until I changed from context to this.
I don't get any errors but I get nothing when I press the forgot password button on the emulator.
The button is there and can be pressed with no errors but still nothing appears.
i fixed it nevermind sorry the answer was changing the navigation method to Navigator.pushNamed
I Just slightly edited your code
Wrap your runApp with MaterialApp
from
void main() {
runApp(
MyApp(),
);
}
to
void main() {
runApp(
MaterialApp(
home: MyApp(),
),
);
}
your full code
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: MyApp(),
),
);
}
class MyApp extends StatefulWidget {
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
createAlertDialogue(BuildContext context) {
TextEditingController customeController = TextEditingController();
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text(" Your NAme"),
content: TextField(
controller: customeController,
),
actions: <Widget>[
MaterialButton(
elevation: 5.0,
child: Text('submit'),
onPressed: () {},
)
],
);
});
}
Widget _buildForgotPasswordBtn(BuildContext ctx) {
return Container(
alignment: Alignment.centerRight,
child: TextButton(
onPressed: () {
setState(() {
createAlertDialogue(ctx);
});
},
child: Text(
'forgot password',
),
),
);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Color.fromARGB(206, 5, 42, 146),
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_buildForgotPasswordBtn(context),
],
),
),
),
);
}
}

Can someone check my Dart code and tell me where I'm making mistake in returning data from my screen as a ListView

I am stuck here for the past 20 days in returning data in my app from the other screen. I'm new to programming and need help. I've been searching through all the internet to find an answer related to my query but nothing is helping though. I ask my fellow SO guys to please help.
You can look at the entire code which I've made open here.
My code:
class SecondPage extends StatefulWidget {
#override
_SecondPageState createState() => _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(30),
child: Stack(
alignment: Alignment.bottomRight,
children: <Widget>[
FloatingActionButton(
child: Icon(
Icons.add,
color: Colors.blue,
),
onPressed: () async {
final newList = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FavoriteList(),
),
);
setState(() {
return ListView.builder(
itemCount: newList.length,
itemBuilder: (context, index){
return Container(
child: Text('item: $newList'),
);
},
);
});
},
)
],
),
);
}
}
The screen where Navigator.pop() is used:
final Set saved = Set();
class FavoriteList extends StatefulWidget {
#override
_FavoriteListState createState() => _FavoriteListState();
}
class _FavoriteListState extends State<FavoriteList> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add to Favorites!'),
centerTitle: true,
backgroundColor: Colors.red),
body: SafeArea(
child: ListView.builder(
itemCount: 53,
itemBuilder: (context, index) {
return CheckboxListTile(
activeColor: Colors.red,
checkColor: Colors.white,
value: saved.contains(index),
onChanged: (val) {
setState(() {
// isChecked = val; // changed
// if(val == true){ // changed
// __saved.add(context); // changed
// } else{ // changed
// __saved.remove(context); // changed
// } // changed
if (val == true) {
saved.add(index);
} else {
saved.remove(index);
}
});
},
title: Row(
children: <Widget>[
Image.asset('lib/images/${images[index]}'),
SizedBox(
width: 10,
),
Text(nameOfSite[index]),
],
),
);
},
),
),
floatingActionButton: FloatingActionButton(
foregroundColor: Colors.red,
child: Icon(Icons.check),
onPressed: () {
Navigator.pop<Set>(context, saved);
},
),
);
}
}
Here is the SecondPage and FavoriteList that I made
import 'package:flutter/material.dart';
import 'package:aioapp2/lists.dart';
Set<int> favorites = {};
class SecondPage extends StatefulWidget {
#override
_SecondPageState createState() => _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
#override
Widget build(BuildContext context) {
return Stack(
fit: StackFit.expand,
children: <Widget>[
_getFavoriteList(),
Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: FloatingActionButton(
child: Icon(
Icons.edit,
color: Colors.blue,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EditFavorites(),
),
).then((updatedFavorites) {
if (updatedFavorites != null)
setState(() {
favorites = updatedFavorites;
});
});
},
),
),
)
],
);
}
Widget _getFavoriteList() {
if (favorites?.isNotEmpty == true)
return _FavoriteList();
else
return _EmptyFavoriteList();
}
}
class _EmptyFavoriteList extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
child: SingleChildScrollView(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Add Your Favorite Sites Here!❤',
style: TextStyle(color: Colors.white),
),
Icon(
Icons.favorite,
size: 150,
color: Colors.blue[100],
),
],
),
),
),
),
],
);
}
}
class _FavoriteList extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: favorites.length,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(
backgroundImage: AssetImage('lib/images/${images[index]}'),
),
title: Text(nameOfSite[favorites.elementAt(index)]),
);
},
);
}
}
//Its FavoriteList Page. I changed the name
class EditFavorites extends StatefulWidget {
#override
_EditFavoritesState createState() => _EditFavoritesState();
}
class _EditFavoritesState extends State<EditFavorites> {
final _editableFavorites = <int>{};
#override
void initState() {
_editableFavorites.addAll(favorites);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add to Favorites!'),
centerTitle: true,
backgroundColor: Colors.red,
actions: <Widget>[
IconButton(
icon: Icon(Icons.done),
onPressed: () {
Navigator.pop<Set>(context, _editableFavorites);
},
)
],
),
//backgroundColor: Colors.indigo,
body: SafeArea(
child: ListView.builder(
itemCount: nameOfSite.length,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(
backgroundImage: AssetImage('lib/images/${images[index]}'),
),
title: Text(nameOfSite[index]),
trailing: IconButton(
icon: _editableFavorites.contains(index)
? Icon(
Icons.favorite,
color: Colors.red,
)
: Icon(
Icons.favorite_border,
color: Colors.grey,
),
onPressed: () {
setState(() {
if (_editableFavorites.contains(index))
_editableFavorites.remove(index);
else
_editableFavorites.add(index);
});
},
),
);
},
),
),
);
}
}
Just replace secondtab.dart with this code.
You can copy paste run full code below
You have to move out return ListView to the same layer with FloatingActionButton
working demo
full code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SecondPage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class SecondPage extends StatefulWidget {
#override
_SecondPageState createState() => _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
Set newList = {};
#override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(30),
child: Stack(
alignment: Alignment.bottomRight,
children: <Widget>[
ListView.builder(
itemCount: newList.length,
itemBuilder: (context, index) {
return Container(
child: Text('item: ${newList.elementAt(index)}'),
);
},
),
FloatingActionButton(
child: Icon(
Icons.add,
color: Colors.blue,
),
onPressed: () async {
newList = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FavoriteList(),
),
);
setState(() {});
},
)
],
),
);
}
}
final Set saved = Set();
class FavoriteList extends StatefulWidget {
#override
_FavoriteListState createState() => _FavoriteListState();
}
class _FavoriteListState extends State<FavoriteList> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Add to Favorites!'),
centerTitle: true,
backgroundColor: Colors.red),
body: SafeArea(
child: ListView.builder(
itemCount: 53,
itemBuilder: (context, index) {
return CheckboxListTile(
activeColor: Colors.red,
checkColor: Colors.white,
value: saved.contains(index),
onChanged: (val) {
setState(() {
// isChecked = val; // changed
// if(val == true){ // changed
// __saved.add(context); // changed
// } else{ // changed
// __saved.remove(context); // changed
// } // changed
if (val == true) {
saved.add(index);
} else {
saved.remove(index);
}
});
},
title: Row(
children: <Widget>[
//Image.asset('lib/images/${images[index]}'),
SizedBox(
width: 10,
),
Text('nameOfSite[index]'),
],
),
);
},
),
),
floatingActionButton: FloatingActionButton(
foregroundColor: Colors.red,
child: Icon(Icons.check),
onPressed: () {
Navigator.pop<Set>(context, saved);
},
),
);
}
}

Alert box with multi select chip in flutter

I have a multiselect chip in my app , but when since the data in the AlertDialog depends dynamically, it will be 1 or 100, so I have added SingleChildScrollView over the alert Dialog to give scrolling if there are more entries , but when I added SingleChildScrollView my alert box goes to top of the screen like this, I want it to align in center,
If I removed the SingleChildScrollView then It will come like this which I wanted. but If there are lot of entries I cant select because It cant cover the entire data?
Is there any way where I can align it to center of screen with scroll enabled?
Thanks
showDialog(
context: context,
builder: (BuildContext context) {
return SingleChildScrollView(
child: AlertDialog(
title: Text("choose items"),
content: MultiSelectChip(
reportList,
onSelectionChanged: (selectedList) {
setState(() {
listSelectedItem = selectedList;
});
},
),
actions: <Widget>[
FlatButton(
child: Text("CANCEL"),
onPressed: () {
setState(() {
dropdownSelected = null;
listSelectedItem.clear();
});
Navigator.of(context).pop();
}),
In AlertDialog's content use Container and constraints, and in Container's child wrap SingleChildScrollView then wrap MultiSelectChip
code snippet
return AlertDialog(
title: Text("Report Video"),
content: Container(
constraints: BoxConstraints(
maxHeight: 100.0,
),
child: SingleChildScrollView(
child: MultiSelectChip(
reportList,
onSelectionChanged: (selectedList) {
setState(() {
selectedReportList = selectedList;
});
},
),
),
),
actions: <Widget>[
FlatButton(
child: Text("Report"),
onPressed: () => Navigator.of(context).pop(),
)
],
);
})
full code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> reportList = [
"Not relevant",
"Illegal",
"Spam",
"Offensive",
"Uncivil",
"a123",
"b234",
"c2314",
"aaaa",
"a",
"1Not relevant",
"2Illegal",
"3Spam",
"4Offensive",
"5Uncivil",
"6a123",
"7b234",
"8c2314",
"9aaaa",
"0a",
"Not relevant",
"Illegal",
"Spam",
"Offensive",
"Uncivil",
"a123",
"b234",
"c2314",
"aaaa",
"a",
"1Not relevant",
"2Illegal",
"3Spam",
"4Offensive",
"5Uncivil",
"6a123",
"7b234",
"8c2314",
"9aaaa",
"0a",
];
List<String> selectedReportList = List();
_showReportDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
//Here we will build the content of the dialog
return AlertDialog(
title: Text("Report Video"),
content: Container(
constraints: BoxConstraints(
maxHeight: 100.0,
),
child: SingleChildScrollView(
child: MultiSelectChip(
reportList,
onSelectionChanged: (selectedList) {
setState(() {
selectedReportList = selectedList;
});
},
),
),
),
actions: <Widget>[
FlatButton(
child: Text("Report"),
onPressed: () => Navigator.of(context).pop(),
)
],
);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text("Report"),
onPressed: () => _showReportDialog(),
),
Text(selectedReportList.join(" , ")),
],
),
),
);
}
}
class MultiSelectChip extends StatefulWidget {
final List<String> reportList;
final Function(List<String>) onSelectionChanged;
MultiSelectChip(this.reportList, {this.onSelectionChanged});
#override
_MultiSelectChipState createState() => _MultiSelectChipState();
}
class _MultiSelectChipState extends State<MultiSelectChip> {
// String selectedChoice = "";
List<String> selectedChoices = List();
_buildChoiceList() {
List<Widget> choices = List();
widget.reportList.forEach((item) {
choices.add(Container(
padding: const EdgeInsets.all(2.0),
child: ChoiceChip(
label: Text(item),
selected: selectedChoices.contains(item),
onSelected: (selected) {
setState(() {
selectedChoices.contains(item)
? selectedChoices.remove(item)
: selectedChoices.add(item);
widget.onSelectionChanged(selectedChoices);
});
},
),
));
});
return choices;
}
#override
Widget build(BuildContext context) {
return Wrap(
children: _buildChoiceList(),
);
}
}

flutter: Another exception was thrown: No MaterialLocalizations found

I am trying to show an Alert Dialog on press of a button in Flutter.
Following is my code
main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Different Widgets",
debugShowCheckedModeBanner: false,
home: showAlertDialog()
);
}
void _dialogResult(String value) {
if (value == "YES") {
print("YES");
} else {
print("NO");
}
Navigator.pop(context);
}
Widget showAlertDialog() {
TextEditingController textEditingController = TextEditingController();
return Scaffold(
appBar: AppBar(
title: Text("Different Widgets"),
),
body: Container(
child: Center(
child: Column(
children: <Widget>[
TextField(
controller: textEditingController,
),
RaisedButton(
onPressed: () {
print("Hi");
AlertDialog dialog = AlertDialog(
title: Text("Hi"),
content: Text(
textEditingController.text,
style: TextStyle(fontSize: 30.0),
),
actions: <Widget>[
FlatButton(
onPressed: () {
_dialogResult("YES");
},
child: Text("YES")),
FlatButton(
onPressed: () {
_dialogResult("NO");
},
child: Text("NO")),
],
);
showDialog(context: context, builder: (BuildContext context) => dialog);
},
child: Text("Click Me"),
)
],
),
),
),
);
}
What does this has to do with Localisation, I cannot follow. I did the same steps as per the docs. I am able to see the button but on click of that button I keep getting error. I tried writing print statement inside of button click and the print statement appears in the log, definitely something wrong with AlertDialog.
You may get No MaterialLocalizations found error while showing dialog using showDialog() class in Flutter. The issue is putting child widget on home property of MaterialApp() widget without creating new widget class.
One way to solve is putting MaterialApp() inside runApp() and create new class for home property.
import 'package:flutter/material.dart';
main() {
runApp(
MaterialApp(
home: MyApp(),
title: "Different Widgets",
debugShowCheckedModeBanner: false,
),
);
}
/*
place MaterialApp() widget on runApp() and create
new class for its 'home' property
to escape 'No MaterialLocalizations found' error
*/
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return showAlertDialog();
}
void _dialogResult(String value) {
if (value == "YES") {
print("YES");
} else {
print("NO");
}
Navigator.pop(context);
}
Widget showAlertDialog() {
TextEditingController textEditingController = TextEditingController();
return Scaffold(
appBar: AppBar(
title: Text("Different Widgets"),
),
body: Container(
child: Center(
child: Column(
children: <Widget>[
TextField(
controller: textEditingController,
),
RaisedButton(
onPressed: () {
print("Hi");
AlertDialog dialog = AlertDialog(
title: Text("Hi"),
content: Text(
textEditingController.text,
style: TextStyle(fontSize: 30.0),
),
actions: <Widget>[
FlatButton(
onPressed: () {
_dialogResult("YES");
},
child: Text("YES")),
FlatButton(
onPressed: () {
_dialogResult("NO");
},
child: Text("NO")),
],
);
showDialog(
context: context,
builder: (BuildContext context) => dialog);
},
child: Text("Click Me"),
)
],
),
),
),
);
}
}