How to validate only one field in a Flutter form? - flutter

I have a form with several fields, at the end of the form there is a Login button which validates the whole form before submit. Within the form there is a "Send Code" button which requires only the email address as mandatory field. How can I just highlight the email address field without highlighting the password field when the Send Code button is pressed?
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Form(
key: _formKey,
child: Column(children: [
Row(children: [
Expanded(
child: TextFormField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email Address'),
controller: _EmailAddressController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter email';
}
return null;
},
),
),
Expanded(
child: TextButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing Data')),
);
}
},
child: Text('Send Code',
style: TextStyle(
fontSize: 24,
color: Colors.green[800],
fontWeight: FontWeight.bold)),
),
)
]),
SizedBox(height: 10),
TextFormField(
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(), labelText: 'Password'),
controller: _PasswordController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter password';
}
return null;
},
),
TextButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing Data')),
);
}
},
child: Text('Login',
style: TextStyle(
fontSize: 24,
color: Colors.grey[800],
fontWeight: FontWeight.bold)),
),
]
),
),
),
),
);
}

Please try this code
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Form(
key: _formKey,
child: Column(children: [
Row(children: [
Expanded(
child: TextFormField(
decoration: InputDecoration(border: OutlineInputBorder(), labelText: 'Email Address'),
controller: _EmailAddressController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter email';
}
return null;
},
),
),
Expanded(
child: TextButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing Data')),
);
}
},
child: Text('Send Code', style: TextStyle(fontSize: 24, color: Colors.green[800], fontWeight: FontWeight.bold)),
),
)
]),
const SizedBox(height: 10),
TextFormField(
obscureText: true,
decoration: const InputDecoration(border: OutlineInputBorder(), labelText: 'Password'),
controller: _PasswordController,
),
TextButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing Data')),
);
}
},
child: Text('Login', style: TextStyle(fontSize: 24, color: Colors.grey[800], fontWeight: FontWeight.bold)),
),
]),
),
),
),
);
}

You can check if _EmailAddressController has the text then validate for password.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Form(
key: _formKey,
child: Column(children: [
Row(children: [
Expanded(
child: TextFormField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email Address'),
controller: _EmailAddressController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter email';
}
return null;
},
),
),
Expanded(
child: TextButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing Data')),
);
}
},
child: Text('Send Code',
style: TextStyle(
fontSize: 24,
color: Colors.green[800],
fontWeight: FontWeight.bold)),
),
)
]),
SizedBox(height: 10),
TextFormField(
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(), labelText: 'Password'),
controller: _PasswordController,
validator: (value) {
if (!_EmailAddressController.text.isEmpty && (value == null || value.isEmpty)) {//You can also add condition for valid email.
return 'Please enter password';
}
return null;
},
),
TextButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing Data')),
);
}
},
child: Text('Login',
style: TextStyle(
fontSize: 24,
color: Colors.grey[800],
fontWeight: FontWeight.bold)),
),
]
),
),
),
),
);
}

Related

Cant select radio buttons inside the form in flutter

It won't allow me to change the radio button inside the form, the value also does not change no matter what is selected. I have tried the code outside the form and it works fine but when i put it inside the form then it stops working for reasons I do not know.
FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('New User'),
content: Stack(
children: <Widget>[
Positioned(
right: -40.0,
top: -40.0,
child: InkResponse(
onTap: () {
Navigator.of(context).pop();
},
child: CircleAvatar(
child: Icon(Icons.close),
backgroundColor: Colors.blue,
),
),
),
Form(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: EdgeInsets.all(8.0),
child: TextFormField(
controller: nameController,
decoration: InputDecoration(
labelText: 'Name',
),
),
),
Padding(
padding: EdgeInsets.all(8.0),
child: TextFormField(
controller: surnameController,
decoration: InputDecoration(
labelText: 'Surname',
),
),
),
Padding(
padding: EdgeInsets.all(8.0),
child: TextFormField(
controller: userController,
decoration: InputDecoration(
labelText: 'Username',
),
),
),
Padding(
padding: EdgeInsets.all(8.0),
child: TextFormField(
controller: passController,
decoration: InputDecoration(
labelText: 'Password',
),
),
),
Padding(
padding: EdgeInsets.all(8.0),
child: TextFormField(
controller: mobileController,
decoration: InputDecoration(
labelText: 'Mobile num',
),
),
),
Padding(
padding: EdgeInsets.all(8.0),
child: TextFormField(
controller: emailController,
decoration: InputDecoration(
labelText: 'Email',
),
),
),
//radioButtons
Container(
padding: EdgeInsets.all(20),
child: Column(
children: [
Text(
"What is your gender?",
style: TextStyle(fontSize: 18),
),
Divider(),
RadioListTile(
title: Text("Male"),
value: "male",
groupValue: gender,
onChanged: (value) {
setState(() {
gender = value.toString();
});
},
),
RadioListTile(
title: Text("Female"),
value: "female",
groupValue: gender,
onChanged: (value) {
setState(() {
gender = value.toString();
});
},
),
RadioListTile(
title: Text("Other"),
value: "other",
groupValue: gender,
onChanged: (value) {
setState(() {
gender = value.toString();
});
},
)
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: FloatingActionButton(
child: Text("Submit"),
onPressed: () {
//createUser();
print(gender);
Navigator.pop(context);
},
),
)
],
),
),
),
],
),
);
});
},
child: Icon(Icons.person),
backgroundColor: Colors.blue,
),
it has a few text fields and then the radio buttons, the gender variable is declared as a string.
It's Because you are assigned a value in the dialog. Just Wrap Your Alert Dialog Widget with statfulBuilder and then stateState.
example
FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return AlertDialog(
title: const Text('New User'),
content: Stack(
children: <Widget>[
Positioned(
right: -40,
top: -40,
child: InkResponse(
onTap: () {
Navigator.of(context).pop();
},
child: const CircleAvatar(
backgroundColor: Colors.blue,
child: Icon(Icons.close),
),
),
),
Form(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller: nameController,
decoration: const InputDecoration(
labelText: 'Name',
),
),
),
Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller: surnameController,
decoration: const InputDecoration(
labelText: 'Surname',
),
),
),
Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller: userController,
decoration: const InputDecoration(
labelText: 'Username',
),
),
),
Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller: passController,
decoration: const InputDecoration(
labelText: 'Password',
),
),
),
Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller: mobileController,
decoration: const InputDecoration(
labelText: 'Mobile num',
),
),
),
Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller: emailController,
decoration: const InputDecoration(
labelText: 'Email',
),
),
),
//radioButtons
Container(
padding: const EdgeInsets.all(20),
child: Column(
children: [
const Text(
'What is your gender?',
style: TextStyle(fontSize: 18),
),
const Divider(),
RadioListTile(
title: const Text('Male'),
value: 'male',
groupValue: gender,
onChanged: (value) {
setState(() {
gender = value.toString();
});
},
),
RadioListTile(
title: const Text('Female'),
value: 'female',
groupValue: gender,
onChanged: (value) {
setState(() {
gender = value.toString();
});
},
),
RadioListTile(
title: const Text('Other'),
value: 'other',
groupValue: gender,
onChanged: (value) {
setState(() {
gender = value.toString();
});
},
)
],
),
),
Padding(
padding: const EdgeInsets.all(8),
child: FloatingActionButton(
child: const Text('Submit'),
onPressed: () {
//createUser();
print(gender);
Navigator.pop(context);
},
),
)
],
),
),
),
],
),
);
},
);
},
);
},
backgroundColor: Colors.blue,
child: Icon(Icons.person),
);

How to center align widget in Flutter form on web

I am building a flutter project on both app and web. I am having a couple of issues with the login page. First my column widget fills the whole width on Flutter web but I want it to be more central. Secondly I am trying to center align the Don't have an account? Sign up button which has found itself aligning to the left. Please may someone assist. Here's my code and a couple of screenshots
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Center(
child: Card(
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
validator: (value) =>
value!.isEmpty ? 'Email cannot be empty' : null,
onSaved: (value) => _email = value!,
decoration: const InputDecoration(
filled: true,
fillColor: Colors.white,
labelText: 'Email',
hintText: 'Email',
border: OutlineInputBorder(),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
validator: (value) =>
value!.isEmpty ? 'Password cannot be empty' : null,
onSaved: (value) => _password = value!,
decoration: const InputDecoration(
filled: true,
fillColor: Colors.white,
labelText: 'Password',
hintText: 'Password',
border: OutlineInputBorder(),
),
obscureText: true,
),
),
Padding(
padding: const EdgeInsets.all(0),
child: TextButton(
onPressed: () {
Navigator.pushNamed(context, '/resetpassword');
},
child: const Text('Forgot Password?'),
style: TextButton.styleFrom(
primary: Colors.black,
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: validateAndSubmit,
child: const Text('Login'),
style: ElevatedButton.styleFrom(
primary: Colors.black,
onSurface: Colors.black,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15.0)),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
const Text('Dont have an account?'),
TextButton(
onPressed: () {
Navigator.pushNamed(context, '/signup');
},
child: const Text(
'Signup',
style: TextStyle(fontWeight: FontWeight.bold),
),
style: TextButton.styleFrom(
primary: Colors.black,
),
),
],
),
),
],
),
),
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
To center the 'Dont have an account?' text and 'Signup' TextButton,
use mainAxisAlignment in Row.
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,//<-- this
children: [
const Text('Dont have an account?'),
TextButton(
onPressed: () {
Navigator.pushNamed(context, '/signup');
},
child: const Text(
'Signup',
style: TextStyle(fontWeight: FontWeight.bold),
),
style: TextButton.styleFrom(
primary: Colors.black,
),
),
],
),
),
To responsive web and app,
I use this method,
void main() async {
runApp(
const ResponsiveLayout(),
);
}
In my ResponsiveLayout const webScreenSize = 600;
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth > webScreenSize) {
//webscreen
return widget.webScreenLayout; // <-- send user Web screen
} else {
//mobile screen
return widget.mobileScreenLayout; // <-- send user mobile screen
}
},
);
}
Read more about LayoutBuilder -
https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html

Flutter Bottom Sheet and DropDownMenu Problem

I am creating a Firebase Flutter Application, in which the Bottom Sheet and DropDown Menu are conflicting
Since I wanted curved borders on the Bottom Sheet I added:
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
canvasColor: Colors.transparent,
),
Then on my home page on clicking button, on pressed function is triggered:
onPressed: () {
return showModalBottomSheet(
context: context,
builder: (context) {
return Container(
color: Colors.transparent,
child: Container(
padding:
EdgeInsets.symmetric(vertical: 20.0, horizontal: 60.0),
decoration: BoxDecoration(
color: Colors.purple[200],
borderRadius: BorderRadius.only(
topLeft: Radius.circular(25.0),
topRight: Radius.circular(25.0),
)
),
child: bottomSheetPanel(),
)
);
}
);
But when an option is selected from drop down menu
How do I correct it?
Any help will be much appreciated:)
i m posting the code of bottom sheet by using firebase and also have dropdown menu so you can take help from this code.
Widget updatebottomSheet()
{
Size size = MediaQuery.of(context).size;
String _dropDownValue;
String starthoour;
String endhour;
String startminute;
String endminute;
showModalBottomSheet(
enableDrag: false,
isDismissible: false,
isScrollControlled: true,
context: context,
builder:(context)
{
return GestureDetector(
behavior: HitTestBehavior.opaque,
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom+10),
// height: size.height*0.6,
decoration: BoxDecoration(
color: Colors.white,
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(25.0),
child: Container(
decoration: BoxDecoration(
//color: Colors.red,
borderRadius: BorderRadius.circular(20),
),
height: size.height*0.6,
width: double.infinity,
child: Card(
elevation: 4,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
NameField(
controller: teacherid,
icon: Icons.person,
hintText: "Please enter Teacher id",
text: "you not enter name",
onchanged: (value)
{
Administrative.instance.addteacherId=value;
},
),
NameField(
controller:name ,
icon: Icons.meeting_room_outlined,
hintText: "Please enter room no",
text: "you not enter room no",
onchanged: (value)
{
Administrative.instance.room=value;
},
),
FirebaseFirestore.instance.collection("Section").where("collegeId",isEqualTo:cond).snapshots()==null?Container():StreamBuilder(
stream:FirebaseFirestore.instance.collection("Section").where("collegeId",isEqualTo:cond).snapshots(),
builder: (BuildContext context,AsyncSnapshot<QuerySnapshot>snapshot) {
var length = snapshot.data.docs.length;
// DocumentSnapshot ds = snapshot.data.docs[length];
return DropdownButton(
hint: _dropDownValue==null
? Text("Choose Section")
:Text(_dropDownValue,style: TextStyle(color: Colors.blue),),
isExpanded: true,
iconSize: 30,
items:snapshot.data.docs.map((DocumentSnapshot document)
{
return DropdownMenuItem<String>(
value: document.data()["SectionName"],
child: Text(document.data()["SectionName"]),
);
}
).toList(),
onChanged: (value){
setState(() {
_dropDownValue=value;
});
},
);
}
),
SizedBox(height: 10,),
Row(
children: [
Padding(
padding: const EdgeInsets.only(right:8.0),
child: Text("Lecture Start time:",style: TextStyle(color: Colors.black,fontWeight: FontWeight.bold),),
),
Padding(
padding: const EdgeInsets.only(right:20.0),
child: DropdownButton(
hint: starthoour == null
? Text('Choose')
: Text(
starthoour,
style: TextStyle(color: Colors.blue),
),
isExpanded: false,
iconSize: 40.0,
style: TextStyle(color: Colors.blue),
items: ['7 AM', '8 AM', '9 AM',"10 AM","11 AM","12 AM","1 PM","2 PM","3 PM","4 PM","5 PM","6 PM","7 PM","8 PM","9 PM","10 PM"].map(
(val) {
return DropdownMenuItem<String>(
value: val,
child: Text(val),
);
},
).toList(),
onChanged: (val) {
setState(
() {
starthoour = val;
},
);
},
),
),
DropdownButton(
hint: startminute == null
? Text('Choose')
: Text(
startminute,
style: TextStyle(color: Colors.blue),
),
isExpanded: false,
iconSize: 40.0,
style: TextStyle(color: Colors.blue),
items: ['10', '20', '30',"40","50","60"].map(
(val) {
return DropdownMenuItem<String>(
value: val,
child: Text(val),
);
},
).toList(),
onChanged: (val) {
setState(
() {
startminute = val;
},
);
},
),
],
),
SizedBox(height: 20,),
Row(
children: [
Padding(
padding: const EdgeInsets.only(right:8.0),
child: Text("Lecture End time:",style: TextStyle(color: Colors.black,fontWeight: FontWeight.bold),),
),
Padding(
padding: const EdgeInsets.only(right:20.0),
child: DropdownButton(
hint: endhour == null
? Text('Choose')
: Text(
endhour,
style: TextStyle(color: Colors.blue),
),
isExpanded: false,
iconSize: 40.0,
style: TextStyle(color: Colors.blue),
items: ['7 AM', '8 AM', '9 AM',"10 AM","11 AM","12 AM","1 PM","2 PM","3 PM","4 PM","5 PM","6 PM","7 PM","8 PM","9 PM","10 PM"].map(
(val) {
return DropdownMenuItem<String>(
value: val,
child: Text(val),
);
},
).toList(),
onChanged: (val) {
setState(
() {
endhour = val;
},
);
},
),
),
DropdownButton(
hint: endminute == null
? Text('Choose')
: Text(
endminute,
style: TextStyle(color: Colors.blue),
),
isExpanded: false,
iconSize: 40.0,
style: TextStyle(color: Colors.blue),
items: ['10', '20', '30',"40","50","60"].map(
(val) {
return DropdownMenuItem<String>(
value: val,
child: Text(val),
);
},
).toList(),
onChanged: (val) {
setState(
() {
endminute = val;
},
);
},
),
],
),
],
),
),
),
),
),
),
Padding(
padding: const EdgeInsets.only(left: 20.0,right: 20.0,top: 8.0,bottom: 8.0),
child: Container(
width: double.infinity,
height: 60,
child: FlatButton(
color: Colors.black,
onPressed: () {
if(!_formKey.currentState.validate()){
return;
}
else
{
if(_dropDownValue==null||endminute==null||endhour==null||startminute==null||starthoour==null)
{
Fluttertoast.showToast(
msg: "Please choose properly from DropDown",
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.redAccent,
textColor: Colors.white,
fontSize: 16.0
);
}
else
{
_formKey.currentState.validate();
addslot(_dropDownValue,starthoour,startminute,endhour,endminute);
}
}
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Text("Save",style: TextStyle(color: Colors.white,fontSize: 18,fontWeight: FontWeight.bold),),
),
),
),
Padding(
padding: const EdgeInsets.only(left: 20.0,right: 20.0,top: 8.0,bottom: 8.0),
child: Container(
width: double.infinity,
height: 60,
child: FlatButton(
color: Colors.black,
onPressed: (){
Navigator.pop(context);
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Text("Cancel",style: TextStyle(color: Colors.white,fontSize: 18,fontWeight: FontWeight.bold),),
),
),
),
],
),
),
),
);
}
);
}

How to put a space between the AppBar and TextFormField inside a card in flutter?

#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.teal,
),
),
Center(
child: Card(
color: Colors.tealAccent[700],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Container(
height: 600,
width: 350,
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
//email
AppBar(
toolbarHeight: 30,
elevation: 00.0,
title: Text(
'Owner Registration ',
style: TextStyle(
fontSize: 25.0, fontWeight: FontWeight.bold),
),
centerTitle: true,
backgroundColor: Colors.transparent,
),
TextFormField(
maxLines: 1,
minLines: 1,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(5),
labelText: "Enter Email",
fillColor: Colors.white,
filled: true,
border: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(10.0),
borderSide: new BorderSide(),
),
),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value.isEmpty || !value.contains('#')) {
return 'invalid email';
}
return null;
},
),
//password
TextFormField(
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
controller: _passwordController,
validator: (value) {
if (value.isEmpty || value.length <= 5) {
return 'invalid password';
}
return null;
},
),
//Confirm Password
TextFormField(
decoration:
InputDecoration(labelText: 'Confirm Password'),
obscureText: true,
validator: (value) {
if (value.isEmpty ||
value != _passwordController.text) {
return 'invalid password';
}
return null;
},
onSaved: (value) {},
),
SizedBox(
height: 30,
),
RaisedButton(
child: Text('Submit'),
onPressed: () {},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
color: Colors.white,
textColor: Colors.teal,
)
],
),
),
),
),
),
),
],
),
);
}
}
https://i.stack.imgur.com/aj4zr.png
Put a SizedBox in between AppBar and TextFormField in Column.
Put a SizedBox (with no color or same color of background) in between AppBar and TextFormField in Column, As #Lee3 said.
or put :
mainAxisAlignment: MainAxisAlignment.spaceBetween, in your Column
you can put Padding(padding: EdgeInsets.symmetric(vertical: 10)), between the AppBar and TextFromField or as #Lee3 and #Rami Ahmed said, SizedBox with some height in there.

Flutter when using phone keyboard, textbox gets hidden

Im having problems with the phone keyboard getting in the way of the textbox that the user has to write in, due to that the user cant see whats hes writing, heres how it looks like
This is the screen without the keyboard
This is the screen with the keyboard
This is my current code for the textfield
TextFormField(
initialValue: '',
onChanged: (text) {
messageEntered = text;
},
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText:
Translations.of(context).trans('message'),
fillColor: Colors.white,
labelStyle: TextStyle(color: Colors.white)),
),
Is there anyway to prevent this?
Thank you for your time
Edit: this is my page code with the scaffold already wrapped
return showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return StatefulBuilder(builder: (context, setState) {
return WillPopScope(
onWillPop: () {
return Future.value(true);
},
child: Scaffold(
resizeToAvoidBottomPadding: false,
body: Container(
color: Colors.red,
padding: const EdgeInsets.all(16.0),
width: double.infinity,
height: double.infinity,
child: Column(
children: <Widget>[
Container(height: 30),
new Text(
Translations.of(context).trans('sendmessage'),
style: TextStyle(color: Colors.white),
),
Container(
height: 30,
),
DropdownButton(
focusColor: Colors.white,
hint: new Text(
Translations.of(context).trans('sendto'),
style: TextStyle(color: Colors.white),
),
isExpanded: true,
onChanged: (value) {
setState(() => selected = value);
setState(() => toEntered = selected);
},
value: selected,
items: workers.map((worker) {
return DropdownMenuItem(
child: new Text(worker.vNome),
value: worker.vCodigo,
);
}).toList(),
),
Container(
height: 30,
),
TextFormField(
initialValue: date,
onChanged: (text) {
dateEntered = text;
},
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText:
Translations.of(context).trans('date'),
fillColor: Colors.white,
labelStyle: TextStyle(color: Colors.white))),
Container(
height: 30,
),
TextFormField(
initialValue: hour,
onChanged: (text) {
hourEntered = text;
},
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText:
Translations.of(context).trans('hour'),
fillColor: Colors.white,
labelStyle: TextStyle(color: Colors.white))),
Container(
height: 30,
),
TextFormField(
initialValue: '',
onChanged: (text) {
messageEntered = text;
},
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText:
Translations.of(context).trans('message'),
fillColor: Colors.white,
labelStyle: TextStyle(color: Colors.white)),
),
Spacer(),
Row(
children: <Widget>[
FlatButton(
textColor: Colors.white,
color: Colors.red[800],
child: Text(Translations.of(context)
.trans('sendmessage')),
onPressed: () {
sendMessage();
}),
Spacer(),
FlatButton(
textColor: Colors.white,
color: Colors.red[800],
child: Text(Translations.of(context)
.trans('closealert')),
onPressed: () {
setState(() => selected = null);
Navigator.of(context).pop();
}),
],
),
],
),
),
));
});
});
Try this,
return showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (context, setState) {
return WillPopScope(
onWillPop: () {
return Future.value(true);
},
child: Scaffold(
body: LayoutBuilder(
builder: (context, constraint) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: constraint.maxHeight,
),
child: IntrinsicHeight(
child: Container(
color: Colors.red,
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
Container(height: 30),
new Text(
Translations.of(context).trans('sendmessage'),
style: TextStyle(color: Colors.white),
),
Container(
height: 30,
),
DropdownButton(
focusColor: Colors.white,
hint: new Text(
Translations.of(context).trans('sendto'),
style: TextStyle(color: Colors.white),
),
isExpanded: true,
onChanged: (value) {
setState(() => selected = value);
setState(() => toEntered = selected);
},
value: selected,
items: workers.map((worker) {
return DropdownMenuItem(
child: new Text(worker.vNome),
value: worker.vCodigo,
);
}).toList(),
),
Container(
height: 30,
),
TextFormField(
initialValue: date,
onChanged: (text) {
dateEntered = text;
},
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText:
Translations.of(context).trans('date'),
fillColor: Colors.white,
labelStyle: TextStyle(color: Colors.white),
),
),
Container(
height: 30,
),
TextFormField(
initialValue: hour,
onChanged: (text) {
hourEntered = text;
},
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText:
Translations.of(context).trans('hour'),
fillColor: Colors.white,
labelStyle: TextStyle(color: Colors.white),
),
),
Container(
height: 30,
),
TextFormField(
initialValue: '',
onChanged: (text) {
messageEntered = text;
},
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
labelText: Translations.of(context)
.trans('message'),
fillColor: Colors.white,
labelStyle: TextStyle(color: Colors.white),
),
),
Spacer(),
Row(
children: <Widget>[
FlatButton(
textColor: Colors.white,
color: Colors.red[800],
child: Text(Translations.of(context)
.trans('sendmessage')),
onPressed: () {
sendMessage();
},
),
Spacer(),
FlatButton(
textColor: Colors.white,
color: Colors.red[800],
child: Text(
Translations.of(context)
.trans('closealert'),
),
onPressed: () {
setState(() => selected = null);
Navigator.of(context).pop();
},
),
],
),
],
),
),
),
),
);
},
),
),
);
},
);
},
);