Flutter-> TextField hidden by KeyBoard - flutter

i have a problem, when i'm focusing on a TextFormField, my keyBoard come over this one. I have tried so much differents ways.
I have found one single solution but my view begin from the bottom to the top and i want the opposite.
I hope someone got a solution to auto scroll the TextFormField, thank you !
My code here :
final _formKey = GlobalKey<FormState>();
#override
void initState() {
super.initState();
}
#override
void dispose() {
nomController.dispose();
adresseController.dispose();
complementAdresseController.dispose();
villeController.dispose();
codePostalController.dispose();
super.dispose();
}
//controller for get value from TextFormField
TextEditingController nomController = TextEditingController();
TextEditingController adresseController = TextEditingController();
TextEditingController complementAdresseController = TextEditingController();
TextEditingController villeController = TextEditingController();
TextEditingController codePostalController = TextEditingController();
//save value in variables for send data from http request
String nom;
String adresse;
String complement;
String ville;
String codePostal;
final ScrollController _scrollController = ScrollController();
sendFormData() async {
var postUri = Uri.parse("http://51.158.67.16:8000/api/contact/");
var request = new http.MultipartRequest("POST", postUri);
request.fields['name'] = nom;
request.fields['adresse'] = adresse;
request.fields['complement'] = complement;
request.fields['city'] = ville;
request.fields['postalCode'] = codePostal;
print(nom);
print(adresse);
print(complement);
print(ville);
print(codePostal);
request.send().then((response) {
if (response.statusCode == 201) {
print("Uploaded!");
} else {
print(response.statusCode);
}
});
}
validateAndSave() async {
final form = _formKey.currentState;
if (form.validate()) {
setState(() {
nom = nomController.text;
adresse = adresseController.text;
complement = complementAdresseController.text;
ville = villeController.text;
codePostal = codePostalController.text;
});
await sendFormData();
} else {
print('form is invalid');
}
}
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: SafeArea(
top: false,
bottom: false,
child: Container(
color: Color.fromRGBO(22, 22, 22, 1.0),
child: Column(children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0.0),
child: Text(
'Veuillez remplir les champs si dessous afin de nous communiquer l\'emplacement et le nom du monument ou de l\'oeuvre',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontFamily: 'Nunito',
),
),
),
Form(
key: _formKey,
child: Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.fromLTRB(18, 22, 0, 4),
child: Text(
"Nom de l’oeuvre",
style: TextStyle(
color: Colors.white, fontSize: 16),
),
)),
Container(
height: MediaQuery.of(context).size.height / 13,
decoration: BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(10.0))),
padding: EdgeInsets.fromLTRB(18, 0, 18, 0),
child: new TextFormField(
style: TextStyle(color: Colors.white),
controller: nomController,
onChanged: (value) {
setState(() {
nom = value;
});
},
validator: (value) {
if (value.length <= 4) {
showDialog(
barrierDismissible: false,
context: context,
builder: (_) => AlertDialog(
backgroundColor:
Color.fromRGBO(40, 40, 40, 1.0),
titleTextStyle:
TextStyle(color: Colors.white),
title: Text(
"Le nom doit contenir au minimum 4 lettres"),
actions: <Widget>[
FlatButton(
onPressed: () =>
Navigator.pop(context),
child: Text('OK',
style: TextStyle(
fontSize: 18,
color: Colors.white)),
)
],
));
}
return null;
},
textAlign: TextAlign.left,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: 0, horizontal: 10),
hintStyle: TextStyle(
color: Color.fromRGBO(133, 133, 133, 1.0),
fontSize: 16),
suffixIcon: Icon(Icons.search,
color:
Color.fromRGBO(133, 133, 133, 1.0)),
hintText: 'Nom du monument, oeuvre...',
fillColor: Color.fromRGBO(40, 40, 40, 1.0),
filled: true,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(10.0),
)),
),
),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.fromLTRB(18, 22, 0, 4),
child: Text(
"Adresse",
style: TextStyle(
color: Colors.white, fontSize: 16),
),
)),
Container(
height: MediaQuery.of(context).size.height / 13,
decoration: BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(10.0))),
padding: EdgeInsets.fromLTRB(18, 0, 18, 0),
child: TextFormField(
style: TextStyle(color: Colors.white),
controller: adresseController,
onChanged: (value) {
setState(() {
adresse = value;
});
},
textAlign: TextAlign.left,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: 0, horizontal: 10),
hintStyle: TextStyle(
color: Color.fromRGBO(133, 133, 133, 1.0),
fontSize: 16),
suffixIcon: Icon(
Icons.search,
color: Color.fromRGBO(133, 133, 133, 1.0),
),
hintText: '( Optionnel ) Adresse',
fillColor: Color.fromRGBO(40, 40, 40, 1.0),
filled: true,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(10.0),
)),
),
),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.fromLTRB(18, 22, 0, 4),
child: Text(
"Complément d'adresse",
style: TextStyle(
color: Colors.white, fontSize: 16),
),
)),
Container(
height: MediaQuery.of(context).size.height / 13,
decoration: BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(10.0))),
padding: EdgeInsets.fromLTRB(18, 0, 18, 0),
child: TextFormField(
style: TextStyle(color: Colors.white),
controller: complementAdresseController,
onChanged: (value) {
setState(() {
complement = value;
});
},
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: 0, horizontal: 10),
hintStyle: TextStyle(
color: Color.fromRGBO(133, 133, 133, 1.0),
fontSize: 16),
suffixIcon: Icon(Icons.search,
color:
Color.fromRGBO(133, 133, 133, 1.0)),
hintText: '(Optionnel) Complement d’adresse',
fillColor: Color.fromRGBO(40, 40, 40, 1.0),
filled: true,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(10.0),
)),
),
),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.fromLTRB(18, 22, 0, 4),
child: Text(
"Ville",
style: TextStyle(
color: Colors.white, fontSize: 16),
),
)),
Align(
alignment: Alignment.centerLeft,
child: Container(
height: MediaQuery.of(context).size.height / 13,
width: MediaQuery.of(context).size.width / 1.5,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
padding: EdgeInsets.fromLTRB(18, 0, 18, 0),
child: TextFormField(
style: TextStyle(color: Colors.white),
controller: villeController,
onChanged: (value) {
setState(() {
ville = value;
});
},
validator: (value) {
if (value.length <= 2) {
showDialog(
barrierDismissible: false,
context: context,
builder: (_) => AlertDialog(
backgroundColor:
Color.fromRGBO(
40, 40, 40, 1.0),
titleTextStyle: TextStyle(
color: Colors.white),
title: Text(
"La ville doit contenir au minimum 2 lettres"),
actions: <Widget>[
FlatButton(
onPressed: () =>
Navigator.pop(
context),
child: Text('OK',
style: TextStyle(
fontSize: 18,
color: Colors
.white)),
)
]));
}
return null;
},
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: 0, horizontal: 10),
hintStyle: TextStyle(
color: Color.fromRGBO(
133, 133, 133, 1.0),
fontSize: 16),
suffixIcon: Icon(Icons.search,
color: Color.fromRGBO(
133, 133, 133, 1.0)),
hintText: 'Ville',
fillColor:
Color.fromRGBO(40, 40, 40, 1.0),
filled: true,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius:
BorderRadius.circular(10.0),
)),
),
)),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.fromLTRB(18, 22, 0, 4),
child: Text(
"Code Postal",
style: TextStyle(
color: Colors.white, fontSize: 16),
),
)),
Align(
alignment: Alignment.centerLeft,
child: Container(
height: MediaQuery.of(context).size.height / 13,
width: MediaQuery.of(context).size.width / 1.5,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
padding: EdgeInsets.fromLTRB(18, 0, 18, 0),
child: TextFormField(
style: TextStyle(color: Colors.white),
controller: codePostalController,
onChanged: (value) {
setState(() {
codePostal = value;
});
},
validator: (value) {
if (value.length != 5) {
showDialog(
barrierDismissible: false,
context: context,
builder: (_) => AlertDialog(
backgroundColor:
Color.fromRGBO(
40, 40, 40, 1.0),
titleTextStyle: TextStyle(
color: Colors.white),
title: Text(
"Le code postal doit contenir 5 chiffres"),
actions: <Widget>[
FlatButton(
onPressed: () =>
Navigator.pop(
context),
child: Text('OK',
style: TextStyle(
fontSize: 18,
color: Colors
.white)),
)
]));
}
return null;
},
keyboardType: TextInputType.number,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: 0, horizontal: 10),
hintStyle: TextStyle(
color:
Color.fromRGBO(133, 133, 133, 1.0),
fontSize: 16),
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(10.0),
),
suffixIcon: Icon(Icons.search,
color:
Color.fromRGBO(133, 133, 133, 1.0)),
hintText: 'Code postal',
fillColor: Color.fromRGBO(40, 40, 40, 1.0),
filled: true,
),
),
)),
FlatButton(
color: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
onPressed: () async {
await validateAndSave();
},
textColor: Colors.white,
child: Padding(
padding: EdgeInsets.fromLTRB(0, 20, 0, 60),
child: Container(
alignment: Alignment(0, 0),
width: MediaQuery.of(context).size.width / 2,
height: 65,
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(10.0)),
color:
Color.fromRGBO(243, 243, 243, 1.0)),
child: Text(
'ENVOYER',
style: TextStyle(
fontSize: 18,
color: Color.fromRGBO(40, 40, 40, 1.0)),
),
//padding: EdgeInsets.fromLTRB(0, 53, 0, 20),
),
)),
],
))
]))));
}
}```

Your page should contain Scaffold widget to get the auto scroll feature.
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: Scaffold(body: MyPage()), //TODO: Add Scaffold
);
}
}
class MyPage extends StatefulWidget {
#override
_MyPageState createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> {
final _formKey = GlobalKey<FormState>();
#override
void initState() {
super.initState();
}
#override
void dispose() {
nomController.dispose();
adresseController.dispose();
complementAdresseController.dispose();
villeController.dispose();
codePostalController.dispose();
super.dispose();
}
//controller for get value from TextFormField
TextEditingController nomController = TextEditingController();
TextEditingController adresseController = TextEditingController();
TextEditingController complementAdresseController = TextEditingController();
TextEditingController villeController = TextEditingController();
TextEditingController codePostalController = TextEditingController();
//save value in variables for send data from http request
String nom;
String adresse;
String complement;
String ville;
String codePostal;
final ScrollController _scrollController = ScrollController();
sendFormData() async {
var postUri = Uri.parse("http://51.158.67.16:8000/api/contact/");
var request = new http.MultipartRequest("POST", postUri);
request.fields['name'] = nom;
request.fields['adresse'] = adresse;
request.fields['complement'] = complement;
request.fields['city'] = ville;
request.fields['postalCode'] = codePostal;
print(nom);
print(adresse);
print(complement);
print(ville);
print(codePostal);
request.send().then((response) {
if (response.statusCode == 201) {
print("Uploaded!");
} else {
print(response.statusCode);
}
});
}
validateAndSave() async {
final form = _formKey.currentState;
if (form.validate()) {
setState(() {
nom = nomController.text;
adresse = adresseController.text;
complement = complementAdresseController.text;
ville = villeController.text;
codePostal = codePostalController.text;
});
await sendFormData();
} else {
print('form is invalid');
}
}
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: SafeArea(
top: false,
bottom: false,
child: Container(
color: Color.fromRGBO(22, 22, 22, 1.0),
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0.0),
child: Text(
'Veuillez remplir les champs si dessous afin de nous communiquer l\'emplacement et le nom du monument ou de l\'oeuvre',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontFamily: 'Nunito',
),
),
),
Form(
key: _formKey,
child: Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.fromLTRB(18, 22, 0, 4),
child: Text(
"Nom de l’oeuvre",
style: TextStyle(color: Colors.white, fontSize: 16),
),
)),
Container(
height: MediaQuery.of(context).size.height / 13,
decoration: BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(10.0))),
padding: EdgeInsets.fromLTRB(18, 0, 18, 0),
child: new TextFormField(
style: TextStyle(color: Colors.white),
controller: nomController,
onChanged: (value) {
setState(() {
nom = value;
});
},
validator: (value) {
if (value.length <= 4) {
showDialog(
barrierDismissible: false,
context: context,
builder: (_) => AlertDialog(
backgroundColor:
Color.fromRGBO(40, 40, 40, 1.0),
titleTextStyle:
TextStyle(color: Colors.white),
title: Text(
"Le nom doit contenir au minimum 4 lettres"),
actions: <Widget>[
FlatButton(
onPressed: () =>
Navigator.pop(context),
child: Text('OK',
style: TextStyle(
fontSize: 18,
color: Colors.white)),
)
],
));
}
return null;
},
textAlign: TextAlign.left,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: 0, horizontal: 10),
hintStyle: TextStyle(
color: Color.fromRGBO(133, 133, 133, 1.0),
fontSize: 16),
suffixIcon: Icon(Icons.search,
color: Color.fromRGBO(133, 133, 133, 1.0)),
hintText: 'Nom du monument, oeuvre...',
fillColor: Color.fromRGBO(40, 40, 40, 1.0),
filled: true,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(10.0),
)),
),
),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.fromLTRB(18, 22, 0, 4),
child: Text(
"Adresse",
style: TextStyle(color: Colors.white, fontSize: 16),
),
)),
Container(
height: MediaQuery.of(context).size.height / 13,
decoration: BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(10.0))),
padding: EdgeInsets.fromLTRB(18, 0, 18, 0),
child: TextFormField(
style: TextStyle(color: Colors.white),
controller: adresseController,
onChanged: (value) {
setState(() {
adresse = value;
});
},
textAlign: TextAlign.left,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: 0, horizontal: 10),
hintStyle: TextStyle(
color: Color.fromRGBO(133, 133, 133, 1.0),
fontSize: 16),
suffixIcon: Icon(
Icons.search,
color: Color.fromRGBO(133, 133, 133, 1.0),
),
hintText: '( Optionnel ) Adresse',
fillColor: Color.fromRGBO(40, 40, 40, 1.0),
filled: true,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(10.0),
)),
),
),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.fromLTRB(18, 22, 0, 4),
child: Text(
"Complément d'adresse",
style: TextStyle(color: Colors.white, fontSize: 16),
),
)),
Container(
height: MediaQuery.of(context).size.height / 13,
decoration: BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(10.0))),
padding: EdgeInsets.fromLTRB(18, 0, 18, 0),
child: TextFormField(
style: TextStyle(color: Colors.white),
controller: complementAdresseController,
onChanged: (value) {
setState(() {
complement = value;
});
},
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: 0, horizontal: 10),
hintStyle: TextStyle(
color: Color.fromRGBO(133, 133, 133, 1.0),
fontSize: 16),
suffixIcon: Icon(Icons.search,
color: Color.fromRGBO(133, 133, 133, 1.0)),
hintText: '(Optionnel) Complement d’adresse',
fillColor: Color.fromRGBO(40, 40, 40, 1.0),
filled: true,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(10.0),
)),
),
),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.fromLTRB(18, 22, 0, 4),
child: Text(
"Ville",
style: TextStyle(color: Colors.white, fontSize: 16),
),
)),
Align(
alignment: Alignment.centerLeft,
child: Container(
height: MediaQuery.of(context).size.height / 13,
width: MediaQuery.of(context).size.width / 1.5,
decoration: BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(10.0))),
padding: EdgeInsets.fromLTRB(18, 0, 18, 0),
child: TextFormField(
style: TextStyle(color: Colors.white),
controller: villeController,
onChanged: (value) {
setState(() {
ville = value;
});
},
validator: (value) {
if (value.length <= 2) {
showDialog(
barrierDismissible: false,
context: context,
builder: (_) => AlertDialog(
backgroundColor:
Color.fromRGBO(40, 40, 40, 1.0),
titleTextStyle:
TextStyle(color: Colors.white),
title: Text(
"La ville doit contenir au minimum 2 lettres"),
actions: <Widget>[
FlatButton(
onPressed: () =>
Navigator.pop(context),
child: Text('OK',
style: TextStyle(
fontSize: 18,
color: Colors.white)),
)
]));
}
return null;
},
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: 0, horizontal: 10),
hintStyle: TextStyle(
color: Color.fromRGBO(133, 133, 133, 1.0),
fontSize: 16),
suffixIcon: Icon(Icons.search,
color: Color.fromRGBO(133, 133, 133, 1.0)),
hintText: 'Ville',
fillColor: Color.fromRGBO(40, 40, 40, 1.0),
filled: true,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(10.0),
)),
),
)),
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.fromLTRB(18, 22, 0, 4),
child: Text(
"Code Postal",
style: TextStyle(color: Colors.white, fontSize: 16),
),
)),
Align(
alignment: Alignment.centerLeft,
child: Container(
height: MediaQuery.of(context).size.height / 13,
width: MediaQuery.of(context).size.width / 1.5,
decoration: BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(10.0))),
padding: EdgeInsets.fromLTRB(18, 0, 18, 0),
child: TextFormField(
style: TextStyle(color: Colors.white),
controller: codePostalController,
onChanged: (value) {
setState(() {
codePostal = value;
});
},
validator: (value) {
if (value.length != 5) {
showDialog(
barrierDismissible: false,
context: context,
builder: (_) => AlertDialog(
backgroundColor:
Color.fromRGBO(40, 40, 40, 1.0),
titleTextStyle:
TextStyle(color: Colors.white),
title: Text(
"Le code postal doit contenir 5 chiffres"),
actions: <Widget>[
FlatButton(
onPressed: () =>
Navigator.pop(context),
child: Text('OK',
style: TextStyle(
fontSize: 18,
color: Colors.white)),
)
]));
}
return null;
},
keyboardType: TextInputType.number,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
vertical: 0, horizontal: 10),
hintStyle: TextStyle(
color: Color.fromRGBO(133, 133, 133, 1.0),
fontSize: 16),
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(10.0),
),
suffixIcon: Icon(Icons.search,
color: Color.fromRGBO(133, 133, 133, 1.0)),
hintText: 'Code postal',
fillColor: Color.fromRGBO(40, 40, 40, 1.0),
filled: true,
),
),
)),
FlatButton(
color: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
onPressed: () async {
await validateAndSave();
},
textColor: Colors.white,
child: Padding(
padding: EdgeInsets.fromLTRB(0, 20, 0, 60),
child: Container(
alignment: Alignment(0, 0),
width: MediaQuery.of(context).size.width / 2,
height: 65,
decoration: const BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(10.0)),
color: Color.fromRGBO(243, 243, 243, 1.0)),
child: Text(
'ENVOYER',
style: TextStyle(
fontSize: 18,
color: Color.fromRGBO(40, 40, 40, 1.0)),
),
//padding: EdgeInsets.fromLTRB(0, 53, 0, 20),
),
),
),
],
),
)
],
),
),
),
);
}
}

I already got a scaffold on my main, i change my widget when icon was clicked on my bottom Navigation bar
my main here:
import 'dart:async';
import 'package:device_id/device_id.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:projet_malvoyant/userScreen.dart';
import 'package:statusbar/statusbar.dart';
import 'downloadScreen.dart';
import 'homePageScreen.dart';
import 'contactScreen.dart';
import 'appBar/contactAppBar.dart';
import 'appBar/downloadAppBar.dart';
import 'device_id.dart';
HomePageScreenState accessLocation;
Timer timer;
void main() async {
runApp(MyApp());
//timer = Timer.periodic(Duration(seconds: 10), (Timer t) => accessLocation.getOeuvreThemeFromLocation());
}
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
int _selectedPage = 0;
Color color = Color.fromRGBO(155, 155, 155, 1.0);
#override
Widget build(BuildContext context) {
StatusBar.color(Color.fromRGBO(40, 40, 40, 1.0));
// Device_id.main();
Widget content;
Widget contentAppBar;
switch (_selectedPage) {
case 0:
content = HomePageScreen();
//contentAppBar = HomePageAppBar();
break;
case 1:
content = DownloadScreen();
contentAppBar = DownloadAppBar();
break;
case 2:
content = ContactScreen();
contentAppBar = ContactAppBar();
break;
case 3:
content = UserScreen();
break;
}
return MaterialApp(
title: '',
home: Scaffold(
resizeToAvoidBottomPadding: false,
resizeToAvoidBottomInset: false,
backgroundColor: Color.fromRGBO(22, 22, 22, 1.0),
appBar: contentAppBar,
body: content,
bottomNavigationBar: bottomNavBar(context)));
}
Widget bottomNavBar(BuildContext context) {
return BottomNavigationBar(
currentIndex: _selectedPage,
onTap: (int index) {
setState(() {
_selectedPage = index;
});
},
iconSize: 24.0,
showSelectedLabels: false,
showUnselectedLabels: false,
type: BottomNavigationBarType.fixed,
backgroundColor: Color.fromRGBO(40, 40, 40, 1.0),
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(
IconData(
67,
fontFamily: 'Glyphter',
),
color: Colors.white,
size: 27),
title: Text('Accueil'),
),
BottomNavigationBarItem(
icon: Icon(
IconData(
66,
fontFamily: 'Glyphter',
),
color: Colors.white,
size: 27),
title: Text('Téléchargement')),
BottomNavigationBarItem(
icon: Icon(
IconData(
68,
fontFamily: 'Glyphter',
),
color: Colors.white,
size: 27,
),
title: Text(
'',
)),
BottomNavigationBarItem(
icon: Icon(
IconData(
65,
fontFamily: 'Glyphter',
),
color: Colors.white,
size: 27),
title: Text('Courriel')),
],
);
}
}

//Add this line "resizeToAvoidBottomInset: true," to your Scaffold and put your main container in ScrollView.
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
key: _scaffoldKey,
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Container()
),
);
}

Related

Could not find a generator for route RouteSettings("/sendotp", null) in the _WidgetsAppState

I want to navigate from one page to another on flutter but i am getting this error what to do The code Is given below
Route.dart
class MyRoute{
static String loginroute = "/login" ;
static String homeroute = "/homepage";
static String registeroute = "/register";
static String ourserviceroute = "/ourservice";
static String aboutusroute = "/about";
static String contactusroute = "/contact";
static String settingspageroute = "/setting";
static String sendotproute = "/sendotp";
}
The register.dart is
import 'package:app_first/utilities/route.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class RegisterPage extends StatefulWidget {
const RegisterPage({super.key});
#override
State<RegisterPage> createState() => _RegisterPageState();
}
class _RegisterPageState extends State<RegisterPage> {
bool isloading = false;
final _formkey=GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Center(child: Text("FOODIES#CU"),)
),
body: Center(
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 130, horizontal: 40),
child: SingleChildScrollView(
child: Form(
key: _formkey,
child: Column(
children: [
TextFormField(
decoration: InputDecoration(
hintText: ("Enter your name"),
labelText: ("Name"),
/* border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25),
borderSide: const BorderSide(
width: 0,
style: BorderStyle.solid,
)
),*/
),
validator: (value) {
if (value!.isEmpty) {
return "NAME CANNOT BE EMPTY";
}
return null;
},
),
SizedBox(
height: 15,
),
TextFormField(
decoration: InputDecoration(
hintText: ("Enter your username"),
labelText: ("Username"),
/*border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25),
borderSide: const BorderSide(
width: 0,
style: BorderStyle.solid,
)
),*/
),
validator: (value) {
if(value!.isEmpty)
{
return "USERNAME CANNOT BE EMPTY";
}
return null;
},
),
SizedBox(
height: 15,
),
TextFormField(
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly,
],
decoration: InputDecoration(
hintText: ("Enter your mobile no."),
labelText: ("Mobile no."),
/*border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25),
borderSide: const BorderSide(
width: 0,
style: BorderStyle.solid,
)
),*/
),
validator: (value) {
if(value!.isEmpty){
return "MOBILE NO. CANNOT BE EMPTY";
}
else if(value.length<=10){
return "MOBILE NUMBER MUST BE OF 10 DIGITS";
}
return null;
},
),
SizedBox(
height: 15,
),
TextFormField(
decoration: InputDecoration(
hintText: ("Enter your email "),
labelText: ("Email"),
suffixIcon: TextButton(
onPressed: (){
Navigator.pushNamed(context, MyRoute.sendotproute);
},
child: Text("Send otp"))
/* border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25),
borderSide: const BorderSide(
width: 0,
style: BorderStyle.solid,
)
),*/
),
validator: (value) {
if(value!.isEmpty)
{
return "EMAIL CANNOT BE EMPTY";
}
return null;
},
),
SizedBox(
height: 15,
),
TextFormField(
obscureText: true,
decoration: InputDecoration(
hintText: ("Enter your password"),
labelText: ("Password"),
/*border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25),
borderSide: const BorderSide(
width: 0,
style: BorderStyle.solid,
)
),*/
),
validator: (password) {
if(password!.isEmpty){
return "PASSWORD CANNOT BE EMPTY";
}
else if(password.length<8){
return "PASSWORD MUST BE ATLEAST 8 DIGITS";
}
return null;
},
),
SizedBox(
height: 15,
),
TextFormField(
obscureText: true,
decoration: InputDecoration(
hintText: ("Enter confirm password"),
labelText: ("Confirm Password"),
/* border: OutlineInputBorder(
borderRadius: BorderRadius.circular(25),
borderSide: const BorderSide(
width: 0,
style: BorderStyle.solid,
)
),*/
),
validator: (value) {
if(value!.isEmpty){
return "CONFIRM PASSWORD CANNOT BE EMPTY";
}
else if(value.length<8){
return "CONFIRM PASSWORD MUST BE ATLEAST 8 DIGITS";
}
return null;
},
),
SizedBox(height: 30,),
Material(
borderRadius: BorderRadius.circular(6),
color: Colors.blueGrey,
child: InkWell(
onTap: ()async
{
if(_formkey.currentState!.validate()){
setState(() {
isloading=true;
});
setState(() {
isloading = true;
});
await Future.delayed(Duration(seconds: 1));
Navigator.pushNamed(context, MyRoute.loginroute);
setState(() {
isloading=false;
});
}
},
child: AnimatedContainer(
duration: Duration(seconds: 1),
width: 140,
height: 40,
//color: Colors.blueGrey,
alignment: Alignment.center,
child: Text("Register now",
style: TextStyle(
//fontWeight: FontWeight.bold,
color: Colors.white,
),
),
/*decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: Colors.blueGrey,*/
),
),
),
],
),
),
),
)
),
);
}
}
And the drawer.dart is
import 'package:app_first/utilities/route.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
class MyDrawer extends StatelessWidget {
const MyDrawer({super.key});
#override
Widget build(BuildContext context) {
Image.asset("assets/images/profile.png");
return Drawer(
backgroundColor: Colors.white,
child: ListView(
children: [
DrawerHeader(
padding: EdgeInsets.zero,
child: UserAccountsDrawerHeader(
accountEmail: Text("Kushagrasinha11111#gmail.com"),
accountName: Text("Kushagra Sinha"),
currentAccountPicture: CircleAvatar(
backgroundImage: AssetImage("assets/images/profile.png"),
)
),
),
ListTile(
leading: Icon(
EvaIcons.homeOutline, color: Color.fromARGB(255, 38, 4, 229),),
title: Text("Home", style:
TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 20,
),),
onTap: () {
Navigator.pushNamed(context, MyRoute.homeroute);
},
),
SizedBox(
height: 3,
),
ListTile(
leading: Icon(
EvaIcons.shoppingCartOutline, color: Color.fromARGB(255, 38, 4, 229),),
title: Text("Our services", style:
TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 20,
),),
onTap: () {
Navigator.pushNamed(context, MyRoute.ourserviceroute);
},
),
SizedBox(
height: 3,
),
ListTile(
leading: Icon(
EvaIcons.bookOpenOutline, color: Color.fromARGB(255, 38, 4, 229),),
title: Text("About us", style:
TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 20,
),),
onTap: () {
Navigator.pushNamed(context, MyRoute.aboutusroute);
},
),
SizedBox(
height: 3,
),
ListTile(
leading: Icon(
EvaIcons.phoneCallOutline, color: Color.fromARGB(255, 38, 4, 229),),
title: Text("Contact us", style:
TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 20,
),),
onTap: () {
Navigator.pushNamed(context, MyRoute.contactusroute);
},
),
SizedBox(
height: 3,
),
ListTile(
leading: Icon(
EvaIcons.settings2Outline, color: Color.fromARGB(255, 38, 4, 229),),
title: Text("Settings", style:
TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 20,
),),
onTap: () {
Navigator.pushNamed(context, MyRoute.settingspageroute);
},
),
SizedBox(
height: 3,
),
ListTile(
leading: Icon(
EvaIcons.logOutOutline, color: Color.fromARGB(255, 38, 4, 229),),
title: Text("Log out", style:
TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 20,
),),
onTap: () {
Navigator.pushNamed(context, MyRoute.loginroute);
},
),
],
),
);
}
}
I am getting the error could not find generator help me with this
I am getting the error could not find the generator help me please

Exception caught by widgets library - Null check operator used on a null value

On the sign-up page when the user enters the email that was used before, this exception happens (Null check operator used on a null value)
[firebase_auth/email-already-in-use] The email address is already in use by another account.
════════ Exception caught by widgets library ═══════════════════════════════════
The following _CastError was thrown building Builder(dirty):
Null check operator used on a null value
this is my code:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:toto/main.dart';
import 'home.dart';
class CreateAccount extends StatefulWidget {
#override
_CreateAccountState createState() => _CreateAccountState();
}
class _CreateAccountState extends State<CreateAccount> {
//FirebaseAuth fireauth = FirebaseAuth.instance;
//FirebaseFirestore firestore = FirebaseFirestore.instance;
final _auth = FirebaseAuth.instance;
final _Key = GlobalKey<FormState>();
final emailController = TextEditingController();
final passwordController = TextEditingController();
final ageController = TextEditingController();
final usernameController = TextEditingController();
final nameController = TextEditingController();
final numericRegex = RegExp(r'[0-9]');
final CharRegex = RegExp(r'[!##\$&*~]');
final LetterRegex = RegExp(r'[a-z A-Z]');
bool isVisible = false;
var errorMessage = '';
//--------------------------------------validations-----------------------
String? validateName(String? formName) {
final nameRegex = RegExp(
r'^[\u0600-\u065F\u066A-\u06EF\u06FA-\u06FFa-zA-Z]+[\u0600-\u065F\u066A-\u06EF\u06FA-\u06FFa-zA-Z-_]{1,20}$');
if (formName == null || formName.isEmpty)
return 'الاسم مطلوب';
else if (!nameRegex.hasMatch(formName))
return 'يجب أن يتكون الأسم من حروف فقط';
else
return null;
}
String? validateEmail(String? formEmail) {
if (formEmail == null || formEmail.isEmpty)
return 'البريد الالكتروني مطلوب';
String pattern = r'\w+#\w+\.\w+';
RegExp regex = RegExp(pattern);
if (!regex.hasMatch(formEmail))
return 'صيغة البريد الالكتروني غير صحيحة';
else
return null;
}
String? validatePassword(String? formPassword) {
if (formPassword == null || formPassword.isEmpty)
return 'كلمة المرور مطلوبة';
else if (formPassword.length < 8)
return 'يجب ان تحتوي كلمة السر على 8 خانات أو أكثر';
else if (!numericRegex.hasMatch(formPassword) &&
!LetterRegex.hasMatch(formPassword))
return 'يجب أن تحتوي كلمة المرور على أرقام وحروف';
else
return null;
}
bool obscure_text = true;
Icon iconfirst = Icon(
Icons.visibility_off,
color: Color.fromARGB(255, 255, 255, 255),
);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body:
//SafeArea(
Container(
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(vertical: 0.0, horizontal: 35.0),
//padding: const EdgeInsets.fromLTRB(0, 70, 0, 0),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/housebg.png'),
fit: BoxFit.cover),
),
child: Center(
child: SingleChildScrollView(
child: Form(
key: _Key,
child: Column(
children: [
SizedBox(
height: 90,
),
Text(
"تسجيل حساب جديد",
style: TextStyle(
fontSize: 33.0,
color: Color.fromARGB(255, 29, 22, 13),
fontWeight: FontWeight.bold,
fontFamily: "ElMessiri"),
),
Padding(
padding: EdgeInsets.fromLTRB(0, 20, 0, 0),
),
//------------------------------name---------------------------------------
SizedBox(
height: 20.0,
),
Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.fromLTRB(0, 0, 30, 0),
child: Text(
"الاسم",
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: "ElMessiri",
fontSize: 16.0,
color: Color.fromARGB(255, 34, 75, 12),
fontWeight: FontWeight.bold,
),
),
),
TextFormField(
controller: nameController,
validator: validateName,
textAlign: TextAlign.right,
cursorColor: Color(0xFF90B28D),
decoration: InputDecoration(
fillColor: Colors.white,
counterText: "",
filled: true,
contentPadding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 10.0),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(30)),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(30)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(30)),
suffixIcon: Icon(
Icons.person,
color: Color(0xFF90B28D),
),
hintText: "الاسم",
hintStyle: TextStyle(
color: Color(0xFF909A99),
),
),
),
//------------------------age---------------------
SizedBox(
height: 10.0,
),
Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.fromLTRB(0, 0, 30, 0),
child: Text(
"العمر",
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: "ElMessiri",
fontSize: 16.0,
color: Color.fromARGB(255, 34, 75, 12),
fontWeight: FontWeight.bold,
),
),
),
TextFormField(
controller: ageController,
textAlign: TextAlign.right,
cursorColor: Color(0xFF90B28D),
decoration: InputDecoration(
fillColor: Colors.white,
counterText: "",
filled: true,
contentPadding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 10.0),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(30)),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(30)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(30)),
suffixIcon: Icon(
Icons.calendar_month,
color: Color(0xFF90B28D),
),
hintText: "العمر",
hintStyle: TextStyle(
color: Color(0xFF909A99),
),
),
keyboardType: TextInputType.number,
),
//------------------------Username-----------------------------
SizedBox(
height: 10.0,
),
Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.fromLTRB(0, 0, 30, 0),
child: Text(
"اسم المستخدم",
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: "ElMessiri",
fontSize: 16.0,
color: Color.fromARGB(255, 34, 75, 12),
fontWeight: FontWeight.bold,
),
),
),
TextFormField(
controller: usernameController,
validator: (value) {
////////// validator /////////////
if (value!.isEmpty) {
return 'يجب ادخال اسم المستخدم';
} else if (value.contains('0')) {
// اشيك في الداتابيس
return 'اسم المستخدم محجوز';
} else
return null;
},
textAlign: TextAlign.right,
decoration: InputDecoration(
fillColor: Colors.white.withOpacity(0.9),
filled: true,
counterText: "",
contentPadding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 10.0),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(30)),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(30)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(30)),
suffixIcon: Icon(
Icons.account_box,
color: Color(0xFF90B28D),
),
hintText: "اسم المستخدم",
hintStyle: TextStyle(
color: Color(0xFF909A99),
),
),
),
//-----------------------------email----------------------------------
SizedBox(
height: 10.0,
),
Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.fromLTRB(0, 0, 30, 0),
child: Text(
"البريد الإلكتروني",
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: "ElMessiri",
fontSize: 16.0,
color: Color.fromARGB(255, 34, 75, 12),
fontWeight: FontWeight.bold,
),
),
),
TextFormField(
controller: emailController,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: validateEmail,
textAlign: TextAlign.right,
cursorColor: Color(0xFF90B28D),
decoration: InputDecoration(
fillColor: Colors.white.withOpacity(0.9),
counterText: "",
filled: true,
contentPadding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 10.0),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(30)),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(30)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(30)),
suffixIcon: Icon(
Icons.mail,
color: Color(0xFF90B28D),
),
hintText: 'email#address.com',
hintStyle: TextStyle(
color: Color(0xFF909A99),
),
),
keyboardType: TextInputType.emailAddress,
),
//-------------------------------password-----------------------------
SizedBox(
height: 10.0,
),
Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.fromLTRB(0, 0, 30, 0),
child: Text(
"كلمة المرور",
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: "ElMessiri",
fontSize: 16.0,
color: Color.fromARGB(255, 34, 75, 12),
fontWeight: FontWeight.bold,
),
),
),
TextFormField(
controller: passwordController,
validator: validatePassword,
textAlign: TextAlign.right,
obscureText: obscure_text,
decoration: InputDecoration(
fillColor: Colors.white.withOpacity(0.9),
counterText: "",
filled: true,
contentPadding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 10.0),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(30)),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(30)),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white),
borderRadius: BorderRadius.circular(30)),
suffixIcon: Icon(
Icons.lock,
color: Color(0xFF90B28D),
),
prefixIcon: GestureDetector(
onTap: () {
setState(() {
if (obscure_text == true) {
obscure_text = false;
iconfirst = Icon(
Icons.visibility,
color: Color(0xFF90B28D),
);
} else {
obscure_text = true;
iconfirst = Icon(
Icons.visibility_off,
color: Colors.grey.shade300,
);
}
});
},
child: iconfirst,
),
hintText: "كلمة المرور",
hintStyle: TextStyle(
color: Color(0xFF909A99),
),
),
),
SizedBox(
height: 20.0,
),
Padding(
padding: EdgeInsets.fromLTRB(0, 20, 0, 0),
),
ElevatedButton(
onPressed: () async {
register(emailController.text.trim(),
passwordController.text);
},
style: ElevatedButton.styleFrom(
fixedSize: Size(280, 40),
backgroundColor: Color(0xFFA03C1B),
elevation: 0.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(30),
),
)),
child: Text(
"تسجيل ",
style: TextStyle(
fontWeight: FontWeight.bold,
fontFamily: "ElMessiri",
fontSize: 22.0,
color: Colors.white),
textAlign: TextAlign.center,
),
),
//////////////////////////////////////// have an account
Container(
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: main,
style: ButtonStyle(
alignment: Alignment.center,
),
child: Text(
"تسجيل دخول",
style: TextStyle(
fontWeight: FontWeight.bold,
fontFamily: "ElMessiri",
fontSize: 16.0,
color: Color.fromARGB(255, 0, 0, 0)),
),
),
Text(
"لديك حساب؟",
style: TextStyle(
fontWeight: FontWeight.bold,
fontFamily: "ElMessiri",
fontSize: 16.0,
color: Color.fromARGB(255, 0, 0, 0)),
),
],
),
),
),
],
),
),
),
),
),
),
);
}
void register(String email, String password) async {
if (_Key.currentState!.validate()) {
try {
await _auth
.createUserWithEmailAndPassword(email: email, password: password)
.then((value) => {postDetailsToFirestore()});
} on FirebaseAuthException catch (error) {
print(error);
errorMessage = error.message!;
Map<String, String?> codeResponses = {
// Re-auth responses
"user-mismatch": 'المستخدم غير متطابق',
"user-not-found": 'لم يتم العثور على المستخدم',
"invalid-credential": 'invalid credential',
"invalid-email": 'الايميل غير موجود',
"wrong-password": 'كلمة المرور الحالية خاطئة',
"invalid-verification-code": 'رمز التحقق غير صالح',
"invalid-verification-id": 'معرّف التحقق غير صالح',
"user-disabled": 'المستخدم لهذا الايميل معطّل',
"too-many-requests": 'طلبات كثيرة',
"operation-not-allowed":
'تسجيل الدخول من خلال الايميل وكلمة المرور غير مسموح',
// Update password error codes
"weak-password": 'كلمة المرور غير قوية',
"requires-recent-login": 'يتطلب تسجيل دخول حديث'
};
showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text(codeResponses[error.code]!),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, 'حسنًا'),
child: const Text('حسنًا'),
)
]);
});
}
}
}
postDetailsToFirestore() async {
User? user = _auth.currentUser;
try {
await FirebaseFirestore.instance.collection("users").doc(user?.uid).set({
'userID': user?.uid,
'name': nameController.text,
'age': ageController.text,
'username': usernameController.text,
'email': emailController.text,
});
print(nameController.text);
print(ageController.text);
print(usernameController.text);
print(emailController.text);
//if(ageController.text>='60'){
Navigator.pushAndRemoveUntil((context),
MaterialPageRoute(builder: (context) => home()), (route) => false);
} on FirebaseAuthException catch (error) {
errorMessage = error.message!;
}
}
}
Two ways to fix this,
Make the below change
showDialog(
context: context,
builder: (context) {
return AlertDialog(
// add -> ?? "Unknown Error" to below line
content: Text(codeResponses[error.code] ?? "Unknown error"),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, 'حسنًا'),
child: const Text('حسنًا'),
)
]);
});
Or
Add email-already-in-use to codeResponses
Map<String, String?> codeResponses = {
// Re-auth responses
"user-mismatch": 'المستخدم غير متطابق',
"user-not-found": 'لم يتم العثور على المستخدم',
"email-already-in-use" : 'Email already in use',

How to make value stay despite leaving the page?

I am trying to make an edit page for users to update their details. I am able to edit the details. But when I leave the page the values go back to the original value it was before editing. How do I make the value stay?
Here is how the screen looks like -
Screen Picture
I did wrap the values in set state thinking that they would remain after leaving the page but they dont.
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:my_plate/screens/home_screen.dart';
import 'package:my_plate/screens/user_guide_screen.dart';
import 'package:my_plate/widgets/app_drawer.dart';
class EditProfilePage extends StatefulWidget {
static String routeName = '/profile';
#override
_EditProfilePageState createState() => _EditProfilePageState();
}
class _EditProfilePageState extends State<EditProfilePage> {
final myController = TextEditingController();
final myController1 = TextEditingController();
String name = 'carolyn1234';
String email = 'carolyn#gmail.com';
final formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
title: Text('Profile'),
backgroundColor: Color(0xff588157),
elevation: 1,
// leading: IconButton(
// icon: Icon(
// Icons.arrow_back,
// color: Colors.white,
// ),
// onPressed: () {
// Navigator.of(context).pushNamed(MainScreen.routeName);
// },
// ),
actions: [
IconButton(
icon: Icon(Icons.library_books_outlined),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UserGuideListScreen(),
));
},
),
],
),
body: Container(
padding: EdgeInsets.only(left: 16, top: 25, right: 16),
child: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: Form(
key: formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: ListView(
children: [
Text(
"Profile",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w800),
),
SizedBox(
height: 15,
),
Center(
child: Stack(
children: [
Container(
width: 130,
height: 130,
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Theme.of(context)
.scaffoldBackgroundColor),
boxShadow: [
BoxShadow(
spreadRadius: 2,
blurRadius: 10,
color: Colors.black.withOpacity(0.1),
offset: Offset(0, 10))
],
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
"https://i.postimg.cc/gj4CDtjX/image.png",
))),
),
Positioned(
bottom: 0,
right: 0,
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
width: 4,
color:
Theme.of(context).scaffoldBackgroundColor,
),
color: Color(0xff588157),
),
child: Icon(
Icons.edit,
color: Colors.white,
),
)),
],
),
),
SizedBox(
height: 35,
),
Text(
'User Details',
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20),
),
SizedBox(height: 10),
Text('Username',
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w400,
color: Colors.black54)),
SizedBox(height: 5),
Container(
child: Text(name),
// margin: const EdgeInsets.all(2.0),
padding: const EdgeInsets.all(10.0),
width: 2000,
decoration: BoxDecoration(
border: Border.all(color: Colors.blueGrey)),
alignment: Alignment.topLeft,
),
SizedBox(height: 10),
Text('Email',
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w400,
color: Colors.black54)),
SizedBox(height: 5),
Container(
child: Text(email),
// margin: const EdgeInsets.all(2.0),
padding: const EdgeInsets.all(10.0),
width: 2000,
decoration: BoxDecoration(
border: Border.all(color: Colors.blueGrey)),
alignment: Alignment.topLeft,
),
SizedBox(
height: 35,
),
Text(
'Edit Details',
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20),
),
SizedBox(
height: 15,
),
TextFormField(
controller: myController,
// initialValue: 'bla123',
// enabled: false,
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xff588157),
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xff588157),
width: 0.0,
),
),
label: Text('Username',
style: TextStyle(color: Colors.black)),
),
validator: (username) {
if (username == null || username.isEmpty)
return 'Field is required.';
else if (username.length < 8)
return 'Please enter a description that is at least 8 characters.';
else
return null;
},
),
SizedBox(
height: 15,
),
TextFormField(
controller: myController1,
// initialValue: 'bla#gmail.com',
// enabled: false,
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xff588157),
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xff588157),
width: 0.0,
),
),
label:
Text('Email', style: TextStyle(color: Colors.black)),
),
validator: (email) {
if (email == null || email.isEmpty)
return 'Field is required.';
String pattern = r'\w+#\w+\.\w+';
if (!RegExp(pattern).hasMatch(email))
return 'Invalid E-mail Address format.';
return null;
},
),
// DropdownButtonFormField(
// // onChanged: null,
// hint: Text('Female'),
// decoration: InputDecoration(
// label: Text('Gender'),
// ),
// items: [
// DropdownMenuItem(child: Text('Female'), value: 'female'),
// DropdownMenuItem(child: Text('Male'), value: 'male'),
// ],
// onChanged: (String? value) {},
// ),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: () {
final isValidForm = formKey.currentState!.validate();
if (isValidForm) {
setState(() {
name = myController.text;
email = myController1.text;
});
}
setState(() {
// name = myController.text;
// email = myController1.text;
});
},
color: Color(0xff588157),
padding: EdgeInsets.symmetric(horizontal: 30),
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
child: Text(
"Update Details",
style: TextStyle(
fontSize: 15,
letterSpacing: 2.2,
color: Colors.white),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: () {
showAlertDialog();
// setState(() {
//
//
// // name = myController.text;
// // email = myController1.text;
// });
},
color: Color(0xff588157),
padding: EdgeInsets.symmetric(horizontal: 30),
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
child: Text(
"Delete Account",
style: TextStyle(
fontSize: 15,
letterSpacing: 2.2,
color: Colors.white),
),
)
],
)
],
),
),
),
),
drawer: AppDrawer());
}
void showAlertDialog() {
// set up the buttons
Widget cancelButton = TextButton(
child: Text("No", style: TextStyle(color: Color(0xff588157))),
onPressed: () {
Navigator.pop(context);
},
);
Widget continueButton = TextButton(
child: Text("Yes", style: TextStyle(color: Color(0xff588157))),
onPressed: () {
setState(() {
name = '';
email = '';
});
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Account deleted successfully!'),
));
Navigator.pop(context);
},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text("AlertDialog"),
content: Text("Are you sure you want to submit this form?"),
actions: [
cancelButton,
continueButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
}

mutation graphql using flutter forms not working

trying to use mutation on forms but got this error while addins runmutation and queryresult result in builder ().all i get is dead code in vscode
The argument type 'Widget Function(MultiSourceResult Function(Map<String, dynamic>, {Object? optimisticResult}), QueryResult<Object?>)' can't be assigned to the parameter type 'Widget Function(MultiSourceResult<Object?> Function(Map<String, dynamic>, {Object? optimisticResult}), QueryResult
import 'dart:io';
import 'package:country_code_picker/country_code_picker.dart';
import 'package:project/API/Api.dart';
import 'package:project/screens/form_info.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import '../API/querys.dart';
import '../API/mutations.dart';
class Sign_Number extends StatefulWidget {
Sign_Number({Key? key}) : super(key: key);
#override
State<Sign_Number> createState() => _Sign_NumberState();
}
class _Sign_NumberState extends State<Sign_Number> {
var PhoneNumber = "";
void _onCountryChange(CountryCode countryCode) {
this.PhoneNumber = countryCode.toString();
print("new country selected: " + countryCode.toString());
}
TextEditingController phoneNumberhere = TextEditingController();
TextEditingController password = TextEditingController();
void initState() {
super.initState();
_onCountryChange(CountryCode());
this.PhoneNumber = "+20";
}
var _formKey1 = new GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return GraphQLProvider(
client: client,
child: MaterialApp(
home: Container(
height: double.infinity,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
stops: [0.5, 0.5],
colors: <Color>[Color.fromRGBO(0, 37, 43, 1), Colors.white],
tileMode:
TileMode.clamp, // clamp the gradient over the canvas
),
),
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.transparent,
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Container(Image(
// height: MediaQuery.of(context).size.height *0.5,
// width: 250,
// image: AssetImage('assets/images/2.jpg')),
// ),
Container(
height: 300,
width: 300,
child: const Image(
image: AssetImage(
'assets/images/2.jpg',
),
fit: BoxFit.cover,
),
),
const SizedBox(
//Use of SizedBox
height: 30,
),
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
child: Row(
children: [
const SizedBox(
width: 47,
),
const Text("Enter mobile number for login",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold)),
],
)),
const SizedBox(
//Use of SizedBox
height: 20,
),
Mutation(
options: new MutationOptions(
document: gql(insertUser()),
/// Tell the GraphQL client to fetch the data from
/// the network only and don't cache it
fetchPolicy: FetchPolicy.noCache,
/// Whenever the [Form] closes, this tells the previous [route]
/// whether it needs to rebuild itself or not
onCompleted: (data) =>
Navigator.pop(context, data != null),
),
builder: (QueryResult, RunMutation) {
return Form(
key: _formKey1,
child: Container(
height: 100,
padding: const EdgeInsets.symmetric(
horizontal: 30),
child: Column(children: [
TextFormField(
controller: phoneNumberhere,
autocorrect: true,
keyboardType:
TextInputType.number,
onFieldSubmitted: (value) {},
validator: (value) {
if (value!.isEmpty) {
return 'Enter a valid Phone Number!';
}
return null;
},
decoration: InputDecoration(
prefixIcon: CountryCodePicker(
onChanged: _onCountryChange,
// Initial selection and favorite can be one of code ('IT') OR dial_code('+39')
initialSelection: '+20',
favorite: ['+20', 'EG'],
textStyle: const TextStyle(
color: Colors.black),
showFlag: true,
),
contentPadding:
const EdgeInsets.all(10),
hintText:
'Enter valid phone number...',
hintStyle: const TextStyle(
color: Colors.black),
filled: true,
fillColor: const Color.fromRGBO(
227, 227, 226, 0.2),
enabledBorder:
const OutlineInputBorder(
borderRadius:
BorderRadius.all(
Radius.circular(
12.0)),
borderSide: BorderSide(
color: Colors.white,
width: 2),
),
focusedBorder:
const OutlineInputBorder(
borderRadius:
BorderRadius.all(
Radius.circular(
10.0)),
borderSide: BorderSide(
color: Colors.white),
),
),
),
const SizedBox(
//Use of SizedBox
height: 10,
),
SizedBox(
height: 50,
child: TextFormField(
autofocus: false,
obscureText: true,
controller: password,
autocorrect: true,
keyboardType: TextInputType
.visiblePassword,
onFieldSubmitted: (value) {},
validator: (value) {
if (value!.isEmpty) {
return 'Enter a valid password!';
}
return null;
},
decoration: InputDecoration(
contentPadding:
const EdgeInsets.all(10),
hintText: 'Enter Password.',
hintStyle: const TextStyle(
color: Colors.black),
filled: true,
fillColor:
const Color.fromRGBO(
227, 227, 226, 0.2),
enabledBorder:
const OutlineInputBorder(
borderRadius:
BorderRadius.all(
Radius.circular(
12.0)),
borderSide: BorderSide(
color: Colors.white,
width: 2),
),
focusedBorder:
const OutlineInputBorder(
borderRadius:
BorderRadius.all(
Radius.circular(
10.0)),
borderSide: BorderSide(
color: Colors.white),
),
),
),
),
const SizedBox(
//Use of SizedBox
height: 5,
),
const Text(
"forgot your password?",
style: TextStyle(
color: Color.fromRGBO(
218, 218, 218, 1),
fontSize: 10),
textAlign: TextAlign.left,
),
])));
const SizedBox(
//Use of SizedBox
height: 50,
);
FlatButton(
height: 50,
minWidth: 300,
onPressed: () {
if (_formKey1.currentState!.validate()) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) =>
MyCustomForm()));
// If the form is valid, display a snackbar. In the real world,
// you'd often call a server or save the information in a database.
ScaffoldMessenger.of(context)
.showSnackBar(
SnackBar(
content:
Text(phoneNumberhere.text)),
);
}
},
color: const Color.fromRGBO(0, 168, 165, 1),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10)),
child: const Text(
"Continue",
style: TextStyle(
color: Colors.white, fontSize: 19),
),
);
},
),
],
)
])))));
}
}```

How to make TextField's label wont move when out of focus in Flutter

I'm new to flutter.
I'm trying to replicate the following UI, it has multiple TextField and all of their labels won't maximize when I click on other TextField, they keep on focus to show the content inside it: https://i.stack.imgur.com/8lUeV.png
The UI I made: https://i.stack.imgur.com/o9Rpj.png
I tried the autofocus: on but it didn't work cuz it only work for one TextField at a time.
My code:
import 'dart:core';
import 'package:flutter/material.dart';
import 'package:login_sample/models/user.dart';
class EmployeeProfile extends StatefulWidget {
const EmployeeProfile({Key? key, required this.user}) : super(key: key);
final User user;
#override
_EmployeeProfileState createState() => _EmployeeProfileState();
}
class _EmployeeProfileState extends State<EmployeeProfile> {
late String name = '';
late String email = '';
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.bottomCenter,
colors: [Colors.blue, Colors.blue])),
height: MediaQuery.of(context).size.height * 0.3
),
Card(
elevation: 20.0,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
topRight: Radius.circular(50),
),
),
margin: const EdgeInsets.only(left: 0.0, right: 0.0, top: 100.0),
child: ListView(
children: <Widget>[
SizedBox(
child: TextField(
autofocus: true,
onChanged: (val){
name = val;
},
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(10.0),
labelText: 'Employee Name',
hintText: widget.user.name,
labelStyle: const TextStyle(
color: Color.fromARGB(255, 107, 106, 144),
fontSize: 14,
fontWeight: FontWeight.w500,
),
border: OutlineInputBorder(
borderSide: const BorderSide(color: Color.fromARGB(255, 107, 106, 144), width: 2),
borderRadius: BorderRadius.circular(10),
),
),
),
width: 150.0,
),
SizedBox(
child: TextField(
autofocus: true,
onChanged: (val){
email = val;
},
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(10.0),
labelText: 'Employee Email',
hintText: widget.user.email,
labelStyle: const TextStyle(
color: Color.fromARGB(255, 107, 106, 144),
fontSize: 14,
fontWeight: FontWeight.w500,
),
border: OutlineInputBorder(
borderSide: const BorderSide(color: Color.fromARGB(255, 107, 106, 144), width: 2),
borderRadius: BorderRadius.circular(10),
),
),
),
width: 150.0,
),
TextButton(
onPressed: (){
print(widget.user.name);
print(widget.user.email);
setState(() {
widget.user.name = name;
widget.user.email = email;
});
},
child: const Text('Save'),
),
],
)
),
Positioned(
top: 0.0,
left: 0.0,
right: 0.0,
child: AppBar(// Add AppBar here only
backgroundColor: Colors.transparent,
elevation: 0.0,
title: Text(
widget.user.name.toString(),
style: const TextStyle(
letterSpacing: 0.0,
fontSize: 20.0,
),
),
),
),
],
),
);
}
}
P/s: sr im not really good at English to describe it correctly
Label will be visible if you focus on the TextField or TextField has content. If what you mean is keeping the label always be visible, you can add floatingLabelBehavior: FloatingLabelBehavior.always on InputDecoration.
import 'dart:core';
import 'package:flutter/material.dart';
import 'package:login_sample/models/user.dart';
class EmployeeProfile extends StatefulWidget {
const EmployeeProfile({Key? key, required this.user}) : super(key: key);
final User user;
#override
_EmployeeProfileState createState() => _EmployeeProfileState();
}
class _EmployeeProfileState extends State<EmployeeProfile> {
late String name = '';
late String email = '';
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.bottomCenter,
colors: [Colors.blue, Colors.blue])),
height: MediaQuery.of(context).size.height * 0.3
),
Card(
elevation: 20.0,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
topRight: Radius.circular(50),
),
),
margin: const EdgeInsets.only(left: 0.0, right: 0.0, top: 100.0),
child: ListView(
children: <Widget>[
SizedBox(
child: TextField(
autofocus: true,
onChanged: (val){
name = val;
},
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(10.0),
labelText: 'Employee Name',
hintText: widget.user.name,
// add here
floatingLabelBehavior: FloatingLabelBehavior.always
labelStyle: const TextStyle(
color: Color.fromARGB(255, 107, 106, 144),
fontSize: 14,
fontWeight: FontWeight.w500,
),
border: OutlineInputBorder(
borderSide: const BorderSide(color: Color.fromARGB(255, 107, 106, 144), width: 2),
borderRadius: BorderRadius.circular(10),
),
),
),
width: 150.0,
),
SizedBox(
child: TextField(
autofocus: true,
onChanged: (val){
email = val;
},
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(10.0),
labelText: 'Employee Email',
hintText: widget.user.email,
// add here
floatingLabelBehavior: FloatingLabelBehavior.always
labelStyle: const TextStyle(
color: Color.fromARGB(255, 107, 106, 144),
fontSize: 14,
fontWeight: FontWeight.w500,
),
border: OutlineInputBorder(
borderSide: const BorderSide(color: Color.fromARGB(255, 107, 106, 144), width: 2),
borderRadius: BorderRadius.circular(10),
),
),
),
width: 150.0,
),
TextButton(
onPressed: (){
print(widget.user.name);
print(widget.user.email);
setState(() {
widget.user.name = name;
widget.user.email = email;
});
},
child: const Text('Save'),
),
],
)
),
Positioned(
top: 0.0,
left: 0.0,
right: 0.0,
child: AppBar(// Add AppBar here only
backgroundColor: Colors.transparent,
elevation: 0.0,
title: Text(
widget.user.name.toString(),
style: const TextStyle(
letterSpacing: 0.0,
fontSize: 20.0,
),
),
),
),
],
),
);
}
}
Try below code hope its helpful to you. add your ListView() inside Padding
Padding(
padding: EdgeInsets.all(20),
child: ListView(
children: <Widget>[
SizedBox(
child: TextField(
autofocus: true,
onChanged: (val) {},
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(10.0),
labelText: 'Employee Name',
hintText: 'widget.user.name',
labelStyle: const TextStyle(
color: Color.fromARGB(255, 107, 106, 144),
fontSize: 14,
fontWeight: FontWeight.w500,
),
border: OutlineInputBorder(
borderSide: const BorderSide(
color: Color.fromARGB(255, 107, 106, 144),
width: 2),
borderRadius: BorderRadius.circular(10),
),
),
),
width: 150.0,
),
SizedBox(
height: 20,
),
SizedBox(
child: TextField(
autofocus: true,
onChanged: (val) {},
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(10.0),
labelText: 'Employee Email',
hintText: 'widget.user.email',
labelStyle: const TextStyle(
color: Color.fromARGB(255, 107, 106, 144),
fontSize: 14,
fontWeight: FontWeight.w500,
),
border: OutlineInputBorder(
borderSide: const BorderSide(
color: Color.fromARGB(255, 107, 106, 144),
width: 2),
borderRadius: BorderRadius.circular(10),
),
),
),
width: 150.0,
),
TextButton(
onPressed: () {},
child: const Text('Save'),
),
],
),
),
Your Screen->