Exception while trying to validate a TextFormField Input - flutter

I am trying to validate two TextFormFields (Email and Password) in my project. But i get an exception while to validate the TextFormField. Can someone let me know where i went wrong? Or how the error can be fixed.
The error i get is : ════════ Exception caught by gesture ═══════════════════════════════════════════ Null check operator used on a null value ════════════════════════════════════════════════════════════════════════════════
My Code :
class _LoginState extends State<Login> {
#override
Widget build(BuildContext context) {
final _formKey = GlobalKey<FormState>();
TextEditingController emailController;
TextEditingController passwordController;
final authService = Provider.of<AuthService>(context);
emailController = TextEditingController();
passwordController = TextEditingController();
return Scaffold(
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Column(children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
child: Container(
width: 300,
height: 380,
decoration:
BoxDecoration(borderRadius: BorderRadius.circular(50.0)),
child: Image.asset(
'assets/images/logo.png',
)),
),
),
const SizedBox(height: 15.0),
Padding(
padding: EdgeInsets.only(left: 25.0, right: 25.0, top: 0, bottom: 0),
child: TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter the email.';
}
return null;
},
controller: emailController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(60),
),
prefixIcon: const Icon(Icons.mail),
labelText: 'E-Mail',
hintText: 'admin#gmail.com'),
),
),
Padding(
padding: EdgeInsets.only(left: 25.0, right: 25.0, top: 15, bottom: 0),
child: TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter the password.';
}
return null;
},
controller: passwordController,
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(60),
),
prefixIcon: const Icon(Icons.vpn_key),
labelText: 'Password',
hintText: 'Enter your Password'),
),
),
const SizedBox(
height: 100,
),
TextButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing')),
);
}
authService.signInWithEmailAndPassword(context,
emailController.text.trim(), passwordController.text.trim());
},
child: const Text(
'Login',
textAlign: TextAlign.center,
)),
MaterialButton(
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => forgotPassword()));
},
child: Text(
'Forgot Password',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 13.0, color: Colors.red.shade900),
))
])),
);
}
}
Thank you in advance.

There is no Form widget used _formKey in your snippet, that's why it is throwing errors from _formKey.currentState!.validate(). Because you are using ! that says currentState of formKey will never get null.
You can do handle it by check null state first.
TextButton(
onPressed: () {
if (_formKey.currentState == null) {
return; // dont execute rest code
}
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing')),
);
authService.signInWithEmailAndPassword(context,
emailController.text.trim(),
passwordController.text.trim());
},
Place Form widget before Column widget.
body: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
More about forms validation

You are causing this error because you have defined a _formkey but not used it in your code so it doesn't have any value or State right now you have to wrap your TextFormField in Form widget and need to pass the defined key, you can check in the code below
final _formKey = GlobalKey<FormState>();
class _LoginState extends State<Login> {
#override
Widget build(BuildContext context) {
TextEditingController emailController;
TextEditingController passwordController;
final authService = Provider.of<AuthService>(context);
emailController = TextEditingController();
passwordController = TextEditingController();
return Scaffold(
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Column(children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
child: Container(
width: 300,
height: 380,
decoration:
BoxDecoration(borderRadius: BorderRadius.circular(50.0)),
child: Image.asset(
'assets/images/logo.png',
)),
),
),
const SizedBox(height: 15.0),
Form(
key: _formKey,
child: Padding(
padding: EdgeInsets.only(left: 25.0, right: 25.0, top: 0, bottom: 0),
child: TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter the email.';
}
return null;
},
controller: emailController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(60),
),
prefixIcon: const Icon(Icons.mail),
labelText: 'E-Mail',
hintText: 'admin#gmail.com'),
),
),
),
Padding(
padding: EdgeInsets.only(left: 25.0, right: 25.0, top: 15, bottom: 0),
child: TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter the password.';
}
return null;
},
controller: passwordController,
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(60),
),
prefixIcon: const Icon(Icons.vpn_key),
labelText: 'Password',
hintText: 'Enter your Password'),
),
),
const SizedBox(
height: 100,
),
TextButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing')),
);
}
authService.signInWithEmailAndPassword(context,
emailController.text.trim(), passwordController.text.trim());
},
child: const Text(
'Login',
textAlign: TextAlign.center,
)),
MaterialButton(
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => forgotPassword()));
},
child: Text(
'Forgot Password',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 13.0, color: Colors.red.shade900),
))
])),
);
}
}

Related

Background orange text removal from button in Dart

Need to change orange color behind button to white. Dont
know where it comes from the code. Brown text is fine but behind orange one needs it to be removed. Maybe some container is taking a style. Tried removing elevated
button.style from shadow color but still not going. Please help with this. Thanks.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:matab/services/authentication_service.dart';
import 'package:matab/ui/general_widgets/generate_error_snackbar.dart';
import 'package:matab/ui/pages/onBoarding/login_page.dart';
import 'package:simple_gradient_text/simple_gradient_text.dart';
import '../styles.dart';
class SignupTextFields extends StatefulWidget {
const SignupTextFields({Key? key}) : super(key: key);
#override
State<SignupTextFields> createState() => _SignupTextFieldsState();
}
class _SignupTextFieldsState extends State<SignupTextFields> {
TextEditingController nameController = TextEditingController();
TextEditingController phoneController = TextEditingController();
TextEditingController userCnicController = TextEditingController();
TextEditingController passwordController = TextEditingController();
TextEditingController emailController = TextEditingController();
TextEditingController confirmPasswordController = TextEditingController();
bool _passwordVisible = false;
#override
Widget build(BuildContext context) {
Authentication authentication = Authentication();
return Padding(
padding: const EdgeInsets.all(10),
child: ListView(
children: <Widget>[
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(10),
child: Text(
'SignUP'.tr,
style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 30),
)),
Container(
padding: const EdgeInsets.all(10),
child: TextField(
controller: nameController,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: 'Name'.tr,
),
),
),
Container(
padding: const EdgeInsets.all(10),
child: TextField(
controller: phoneController,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp('[0-9]'),
),
],
maxLength: 11,
keyboardType: TextInputType.number,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: 'Phone'.tr,
),
),
),
Container(
padding: const EdgeInsets.all(10),
child: TextField(
controller: emailController,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: 'Email'.tr,
),
),
),
Container(
padding: const EdgeInsets.all(10),
child: TextField(
controller: userCnicController,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp('[0-9]'),
),
],
maxLength: 13,
keyboardType: TextInputType.number,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: 'UserCNIC'.tr,
),
),
),
Container(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
child: TextFormField(
keyboardType: TextInputType.text,
controller: passwordController,
obscureText:
!_passwordVisible, //This will obscure text dynamically
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: 'Password'.tr,
suffixIcon: IconButton(
icon: ImageIcon(
const AssetImage("assets/visibilty.png"),
color: greyColor,
),
onPressed: () {
// Update the state i.e. toogle the state of passwordVisible variable
setState(() {
_passwordVisible = !_passwordVisible;
});
},
),
),
),
),
Container(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
child: TextFormField(
keyboardType: TextInputType.text,
controller: confirmPasswordController,
obscureText:
!_passwordVisible, //This will obscure text dynamically
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: 'Confirm Password'.tr,
suffixIcon: IconButton(
icon: ImageIcon(
const AssetImage("assets/visibilty.png"),
color: greyColor,
),
onPressed: () {
// Update the state i.e. toogle the state of passwordVisible variable
setState(() {
_passwordVisible = !_passwordVisible;
});
},
),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20.0, 10, 20, 0),
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(colors: gradientColors),
borderRadius:
const BorderRadius.all(Radius.circular(7.0))),
height: 50,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.transparent,
shadowColor: Colors.transparent,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(82.0)),
),
),
child: Text('Register'.tr),
onPressed: () {
if (nameController.text.isNotEmpty) {
if (phoneController.text.isNotEmpty) {
if (userCnicController.text.trim().length != 13) {
generateError(
"Error".tr, "CNICMustBe13DigitsLong".tr);
} else {
if (emailController.text.isNotEmpty) {
authentication.signUp(
nameController.text,
phoneController.text,
int.tryParse(
userCnicController.text.trim()) ??
0, //cnic never replaced with 0 we have already checked for null
emailController.text,
passwordController.text,
confirmPasswordController.text);
} else {
generateError(
"EmailEmpty".tr, "YouMustProvideEmail".tr);
}
}
} else {
generateError(
"PhoneCannotEmpty".tr, "EnterPhoneTryAgain".tr);
}
} else {
generateError(
"NameCannotBeEmpty".tr, "EnterNameAndTryAgain".tr);
}
},
)),
),
Row(
children: <Widget>[
Text(
'Already have an Account?'.tr,
style: TextStyle(fontSize: 20.0, color: greyColor),
),
TextButton(
child: GradientText(
'Login'.tr,
style: const TextStyle(
fontSize: 20.0,
),
gradientType: GradientType.radial,
radius: 2.5,
colors: gradientColors,
),
onPressed: () {
Get.off(const LoginPage());
},
),
],
mainAxisAlignment: MainAxisAlignment.center,
),
],
));
}
}
For the top container, it is having Radius.circular(7.0) But for Elevated button it is Radius.circular(82.0).
You need to provide same radius on both.
Padding(
padding: const EdgeInsets.fromLTRB(20.0, 10, 20, 0),
child: Container(
decoration: BoxDecoration(
gradient:
LinearGradient(colors: [Colors.red, Colors.black54]),
borderRadius: BorderRadius.all(Radius.circular(82.0)),
),
height: 50,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.transparent,
shadowColor: Colors.transparent,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(82.0)),
),
),
child: Text('Register'),
onPressed: () {},
)),
),
don't use shadowColor: Colors.transparent, instead use
shadowColor: Colors.white,
because the default color of your app is orange so if you do Colors.transparent it'll call default color in some cases. Also you have to remove the parent Contanier from the ElevatedButton because it is taking the background surface and changing it to orange color

Flutter error: The method 'validate' was called on null. Receiver: null Tried calling: validate()

I am currently working on a flutter project. I made a flat button in the bottom and made the function _submit() as the onPressed method. But it seems like _formKey.currentState.validate() is having an error. The error message is like what's shown below
The method 'validate' was called on null.
Receiver: null
Tried calling: validate()
I found similar questions to mine and tried to fix it. But I can't find my mistake.
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class AddTaskScreen extends StatefulWidget {
AddTaskScreen({Key key}) : super(key: key);
#override
_AddTaskScreenState createState() => _AddTaskScreenState();
}
class _AddTaskScreenState extends State<AddTaskScreen> {
final _formKey = GlobalKey<FormState>();
String _title = '';
String _priority;
DateTime _date = DateTime.now();
TextEditingController _dateController = TextEditingController();
final DateFormat _dateFormatter = DateFormat('MMM dd, yyy');
final List<String> _priorities = ['Low', 'Medium', 'High'];
_handleDatePicker() async {
final DateTime date = await showDatePicker(
context: context,
initialDate: _date,
firstDate: DateTime(2000),
lastDate: DateTime(2100));
if (date != null && date != _date) {
setState(() {
_date = date;
});
_dateController.text = _dateFormatter.format(date);
}
}
_submit() {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
print('$_title $_date $_priority');
Navigator.pop(context);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 40.0, vertical: 80.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
GestureDetector(
onTap: () => Navigator.pop(context),
child: Icon(
Icons.arrow_back_ios,
size: 30.0,
color: Colors.black,
),
),
SizedBox(
height: 20.0,
),
Text('Add Task',
style: TextStyle(
color: Colors.black,
fontSize: 40.0,
fontWeight: FontWeight.bold)),
SizedBox(height: 10.0),
Form(
key: _formKey,
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0),
child: TextFormField(
style: TextStyle(fontSize: 18.0),
decoration: InputDecoration(
labelText: 'Title',
labelStyle: TextStyle(fontSize: 18.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0))),
validator: (input) => input.trim().isEmpty
? 'Please enter a task title'
: null,
onSaved: (input) => _title = input,
initialValue: _title),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0),
child: TextFormField(
readOnly: true,
controller: _dateController,
style: TextStyle(fontSize: 18.0),
onTap: _handleDatePicker,
decoration: InputDecoration(
labelText: 'Date',
labelStyle: TextStyle(fontSize: 18.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0))),
)),
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0),
child: DropdownButtonFormField(
icon: Icon(Icons.arrow_drop_down_circle),
iconSize: 22.0,
items: _priorities.map((String priority) {
return DropdownMenuItem(
value: priority,
child: Text(
priority,
style: TextStyle(
color: Colors.black, fontSize: 18.0),
),
);
}).toList(),
style: TextStyle(fontSize: 18.0),
decoration: InputDecoration(
labelText: 'Priority',
labelStyle: TextStyle(fontSize: 18.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0))),
validator: (input) => _priority == null
? 'Please select a priority level'
: null,
onChanged: (value) {
setState(() {
_priority = value;
});
},
value: _priority,
)),
Container(
margin: EdgeInsets.symmetric(vertical: 20.0),
height: 60.0,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(30.0)),
child: FlatButton(
onPressed: _submit(),
child: Text(
'Add',
style: TextStyle(
color: Colors.white, fontSize: 20.0),
)),
)
],
),
)
],
),
),
),
),
);
}
}
You can copy paste run full code below
You can change _submit() to _submit
Because _submit() means execute function
code snippet change from
FlatButton(
onPressed: _submit(),
to
FlatButton(
onPressed: _submit,
working demo
full code
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class AddTaskScreen extends StatefulWidget {
AddTaskScreen({Key key}) : super(key: key);
#override
_AddTaskScreenState createState() => _AddTaskScreenState();
}
class _AddTaskScreenState extends State<AddTaskScreen> {
final _formKey = GlobalKey<FormState>();
String _title = '';
String _priority;
DateTime _date = DateTime.now();
TextEditingController _dateController = TextEditingController();
final DateFormat _dateFormatter = DateFormat('MMM dd, yyy');
final List<String> _priorities = ['Low', 'Medium', 'High'];
_handleDatePicker() async {
final DateTime date = await showDatePicker(
context: context,
initialDate: _date,
firstDate: DateTime(2000),
lastDate: DateTime(2100));
if (date != null && date != _date) {
setState(() {
_date = date;
});
_dateController.text = _dateFormatter.format(date);
}
}
_submit() {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
print('$_title $_date $_priority');
Navigator.pop(context);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 40.0, vertical: 80.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
GestureDetector(
onTap: () => Navigator.pop(context),
child: Icon(
Icons.arrow_back_ios,
size: 30.0,
color: Colors.black,
),
),
SizedBox(
height: 20.0,
),
Text('Add Task',
style: TextStyle(
color: Colors.black,
fontSize: 40.0,
fontWeight: FontWeight.bold)),
SizedBox(height: 10.0),
Form(
key: _formKey,
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0),
child: TextFormField(
style: TextStyle(fontSize: 18.0),
decoration: InputDecoration(
labelText: 'Title',
labelStyle: TextStyle(fontSize: 18.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0))),
validator: (input) => input.trim().isEmpty
? 'Please enter a task title'
: null,
onSaved: (input) => _title = input,
initialValue: _title),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0),
child: TextFormField(
readOnly: true,
controller: _dateController,
style: TextStyle(fontSize: 18.0),
onTap: _handleDatePicker,
decoration: InputDecoration(
labelText: 'Date',
labelStyle: TextStyle(fontSize: 18.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0))),
)),
Padding(
padding: EdgeInsets.symmetric(vertical: 20.0),
child: DropdownButtonFormField(
icon: Icon(Icons.arrow_drop_down_circle),
iconSize: 22.0,
items: _priorities.map((String priority) {
return DropdownMenuItem(
value: priority,
child: Text(
priority,
style: TextStyle(
color: Colors.black, fontSize: 18.0),
),
);
}).toList(),
style: TextStyle(fontSize: 18.0),
decoration: InputDecoration(
labelText: 'Priority',
labelStyle: TextStyle(fontSize: 18.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0))),
validator: (input) => _priority == null
? 'Please select a priority level'
: null,
onChanged: (value) {
setState(() {
_priority = value;
});
},
value: _priority,
)),
Container(
margin: EdgeInsets.symmetric(vertical: 20.0),
height: 60.0,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(30.0)),
child: FlatButton(
onPressed: _submit,
child: Text(
'Add',
style: TextStyle(
color: Colors.white, fontSize: 20.0),
)),
)
],
),
)
],
),
),
),
),
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: AddTaskScreen(),
);
}
}

Upload data to Firebase database

On trying to upload data to the firebase realtime database error comes.
After filling the form data when the save button is pressed.The uploadPic function is called that upload the text from textfield to the firebase, the error message comes on the console of Android Studio.
The screenshot of the error is in the link below.
Code is also mentioned below,
The uploadPic function is at line 72
Code:
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:image_picker/image_picker.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:udharibook/Screens/dashboard.dart';
class UserProfile extends StatefulWidget {
#override
_UserProfileState createState() => _UserProfileState();
}
class _UserProfileState extends State<UserProfile> {
var _formKey = GlobalKey<FormState>();
TextEditingController nameController;
TextEditingController phoneController;
TextEditingController emailController;
TextEditingController addressController;
var profileImage =
'https://firebasestorage.googleapis.com/v0/b/udhari-book.appspot.com/o/DefaultImage.png?alt=media&token=06bddd3e-7f11-476b-a982-dfb21096f9c7';
File _image;
String fileName;
static var userId;
FirebaseAuth _auth = FirebaseAuth.instance;
DatabaseReference DBRef =
FirebaseDatabase.instance.reference().child('Users');
void initState() {
super.initState();
_auth.currentUser().then((curUser) {
userId = curUser.uid;
print('Current user id:' + userId);
DBRef.child(curUser.uid).once().then((DataSnapshot user) {
if (user != null) {
setState(() {
//Provide the initial value of the user in the text field
phoneController = TextEditingController(text: curUser.phoneNumber);
profileImage = user.value['ProfileImage'];
nameController = TextEditingController(text: user.value['Name']);
emailController = TextEditingController(text: user.value['Email']);
addressController =TextEditingController(text: user.value['Address']);
});
}
});
});
}
#override
Widget build(BuildContext context) {
Future getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
_image = image;
fileName = phoneController.text;
StorageReference firebaseStorageRef =
FirebaseStorage.instance.ref().child('Images/$fileName');
StorageUploadTask uploadTask = firebaseStorageRef.putFile(_image);
StorageTaskSnapshot imgSnapshot = await uploadTask.onComplete;
if (imgSnapshot.error == null) {
profileImage = await imgSnapshot.ref.getDownloadURL();
}
setState(() {
print('Image uploaded successfully');
});
}
Future uploadPic(BuildContext context) async {
print('The user name is: '+nameController.text);
DBRef.child(userId).set({
'User Id': userId,
'Name': nameController.text,
'Mobile': fileName,
'Email':emailController.text,
'Address': addressController.text,
'ProfileImage': profileImage,
});
setState(() {
print('Data uploaded Successfully');
//DashboardPage(userName: nameController.text,imgUrl: imgUrl,);
});
}
return Scaffold(
appBar: AppBar(
title: Text('User Profile'),
backgroundColor: Color.fromRGBO(162, 42, 43, 1.0),
),
body: Builder(
builder: (context) => SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
SizedBox(
height: 10.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//Profile Image widget
Align(
alignment: Alignment.center,
child: CircleAvatar(
radius: 70,
backgroundColor: Colors.white,
child: ClipOval(
child: SizedBox(
height: 120.0,
width: 120.0,
child: _image != null
? Image.file(_image, fit: BoxFit.fill)
: Image.network(
profileImage,
fit: BoxFit.fitWidth,
),
),
),
),
),
//Camera Icon Widget
Padding(
padding: EdgeInsets.only(),
child: IconButton(
icon: Icon(Icons.camera_alt),
onPressed: () {
getImage();
}),
)
],
),
//Name TextField
Padding(
padding: EdgeInsets.only(top: 20.0, left: 10.0, right: 10.0),
child: TextFormField(
controller: nameController,
validator: (input) {
if (input.isEmpty) return 'Please enter Name';
},
decoration: InputDecoration(
contentPadding: new EdgeInsets.symmetric(vertical: 5.0,horizontal: 20.0),
labelText: 'Full Name',
labelStyle:
TextStyle(fontFamily: 'Exo2', color: Colors.grey),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
borderSide: BorderSide(
color: Color.fromRGBO(162, 42, 43, 1.0)))),
),
),
//Mobile Text Field
Padding(
padding:
EdgeInsets.only(top: 15.0, left: 10.0, right: 10.0),
child: SizedBox(
height: 40.0,
child: TextField(
controller: phoneController,
enabled: false,
keyboardType: TextInputType.phone,
decoration: InputDecoration(
contentPadding: new EdgeInsets.symmetric(vertical: 5.0,horizontal: 20.0),
labelText: 'Mobile Number',
labelStyle: TextStyle(
fontFamily: 'Exo2', color: Colors.grey),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
borderSide: BorderSide(
color: Color.fromRGBO(162, 42, 43, 1.0)))),
),
)),
//Email Text Field
Padding(
padding: EdgeInsets.only(top: 15.0, left: 10.0, right: 10.0),
child: TextFormField(
controller: emailController,
validator: (input) {
if (input.isNotEmpty && input.contains('#') == false)
return 'Please enter correct Email Id';
else if (input.isEmpty) return 'Please enter Email Id';
},
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
contentPadding: new EdgeInsets.symmetric(vertical: 5.0,horizontal: 20.0),
labelText: 'Email Id',
labelStyle:
TextStyle(fontFamily: 'Exo2', color: Colors.grey),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
borderSide: BorderSide(
color: Color.fromRGBO(162, 42, 43, 1.0)))),
),
),
//Address Text Field
Padding(
padding: EdgeInsets.only(
top: 15.0, left: 10.0, right: 10.0, bottom: 30.0),
child: TextFormField(
maxLines: 3,
maxLengthEnforced: true,
controller: addressController,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Address (Optional)',
labelStyle:
TextStyle(fontFamily: 'Exo2', color: Colors.grey),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
borderSide: BorderSide(
color: Color.fromRGBO(162, 42, 43, 1.0)))),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
//Save Button
SizedBox(
width: 130.0,
height: 50.0,
child: RaisedButton(
color: Color.fromRGBO(162, 42, 43, 1.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0)),
onPressed: () {
if (_formKey.currentState.validate()) {
uploadPic(context);
} else
setState(() {});
},
elevation: 4.0,
splashColor: Colors.blueGrey,
child: Text(
'Save',
style: TextStyle(
color: Colors.white,
fontSize: 22.0,
fontFamily: 'Exo2'),
),
)),
//Cancel Button
SizedBox(
width: 130.0,
height: 50.0,
child: RaisedButton(
color: Color.fromRGBO(162, 42, 43, 1.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0)),
onPressed: () {
Navigator.of(context).pop();
},
elevation: 4.0,
splashColor: Colors.blueGrey,
child: Text(
'Cancel',
style: TextStyle(
color: Colors.white,
fontSize: 22.0,
fontFamily: 'Exo2'),
),
))
],
)
],
),
),
),
),
);
}
}
Replace this :
TextEditingController nameController;
TextEditingController phoneController;
TextEditingController emailController;
TextEditingController addressController;
With this:
TextEditingController nameController = TextEditingController();
TextEditingController phoneController = TextEditingController();
TextEditingController emailController = TextEditingController();
TextEditingController addressController = TextEditingController();
And also replace this
onPressed: () {
if (_formKey.currentState.validate()) {
uploadPic(context);
}
else
setState(() {});
},
with this:
OnPressed: () {
setState(() {
if (_formKey.currentState.validate()) {
uploadPic(context);
} //else
});
},

Clicking in TextFormField causes rebuild and text field subsequently loses focus

My Flutter app has been working fine right up until yesterday at which point my login screen started acting strange. As soon as I click in either the username or password text fields the keyboard shows, immediately hides, and then everything rebuilds. I've seen several threads on similar issues online, but nothing that's helped me figure out what's going wrong here. This is the gist of the code:
static final _formKey = GlobalKey<FormState>();
TextEditingController _emailController = TextEditingController();
TextEditingController _passwordController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(body: SingleChildScrollView(child: _buildBody()));
}
Widget _buildBody() {
return BlocProvider(create: (context) {
_loginBloc = LoginBloc(auth);
return _loginBloc;
}, child: BlocBuilder<LoginBloc, LoginState>(builder: (context, state) {
if (state is LoginFailure) {
_onWidgetDidBuild(() {
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text('${state.error}'),
backgroundColor: Colors.red,
),
);
});
_showErrorMessage(state.error);
}
return Container(
height: Styles().height(),
child: LoadingOverlay(
color: Colors.black,
opacity: 0.5,
isLoading: (state is LoginLoading),
progressIndicator: SpinKitThreeBounce(color: Colors.white),
child: Container(
padding: EdgeInsets.fromLTRB(30, 50, 30, 0),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [AppColors.DARK_BLUE, AppColors.GREEN])),
child: Column(children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 50),
child: _showLogo()),
Card(
color: Colors.white,
elevation: 5,
child: Padding(
padding: EdgeInsets.all(10),
child: Form(
key: _formKey,
child: ListView(
shrinkWrap: true,
children: <Widget>[
_buildEmailInput(),
_buildPasswordInput(),
Padding(
padding: EdgeInsets.only(top: 20),
child: ButtonTheme(
height: 50,
child: FlatButton(
color: AppColors.MEDIUM_GREEN,
child: Text(
_formMode == FormMode.LOGIN
? 'Sign in with Email'
: 'Create Account',
style: TextStyle(
color: Colors.white,
fontSize: 15,
fontWeight:
FontWeight.bold)),
onPressed: _validateAndSubmit,
))),
_showSecondaryButton(),
Align(
alignment: Alignment.center,
child: GestureDetector(
onTap: _showLoginRecoveryModal,
child: Text(
'Forgot Password?',
style: TextStyle(
color: AppColors.LIGHT_BLUE,
fontSize: 15,
fontWeight: FontWeight.bold),
))),
],
),
))),
Padding(
padding: const EdgeInsets.only(top: 20.0, bottom: 20.0),
child: Align(
alignment: Alignment.center,
child: Text(
'OR',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
)),
),
_buildGoogleButton()
]))));
}));
}
Widget _buildEmailInput() {
return Padding(
padding: const EdgeInsets.only(top: 20),
child: TextFormField(
maxLines: 1,
controller: _emailController,
keyboardType: TextInputType.emailAddress,
autofocus: false,
decoration: InputDecoration(
hintText: 'Email',
icon: Icon(
Icons.mail,
color: Colors.grey,
)),
validator: (value) => !EmailEditingRegexValidator().isValid(value)
? 'Invalid email address'
: null,
onSaved: (value) {
if (StringUtils.isNotNullOrEmpty(value)) {
_email = value.trim();
} else {
_email = null;
}
},
),
);
}
Widget _buildPasswordInput() {
return Padding(
padding: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0),
child: TextFormField(
maxLines: 1,
controller: _passwordController,
obscureText: _hidePassword,
autofocus: false,
decoration: InputDecoration(
hintText: 'Password',
icon: Icon(
Icons.lock,
color: Colors.grey,
),
suffix: GestureDetector(
onTap: _toggleShowPassword,
child: Icon(
AntIcons.eye,
color: Colors.grey,
))),
validator: (value) => !NonEmptyStringValidator().isValid(value)
? 'Password can\'t be empty'
: null,
onSaved: (value) {
if (StringUtils.isNotNullOrEmpty(value)) {
_password = value.trim();
} else {
_password = null;
}
},
),
);
}
I'm not sure what I need to do here to ensure that, as soon as the keyboard shows, everything does not get rebuilt.

How to align a Text to the bottom

I'm trying to build a very simple login page, and i want that the "sign up" text to be at the bottom of the screen.
I'm trying to align the text in the last column to the bottom of the screen, but somehow the aligment doesn't work.
When i try to use the Expanded widget, the IDE throw me an paint error.
class EmailLogin extends StatefulWidget {
#override
_EmailLoginState createState() => _EmailLoginState();
}
class _EmailLoginState extends State<EmailLogin> {
final Map<String, dynamic> _formData = {'email': null, 'password': null};
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
Widget _emailTextField() {
return TextFormField(
decoration: InputDecoration(
labelText: 'Email',
),
keyboardType: TextInputType.emailAddress,
},
onSaved: (String value) {
_formData['email'] = value;
},
);
}
Widget _passwordTextField() {
return TextFormField(
obscureText: true,
validator: (String value) {
if (value.isEmpty || value.length < 6) {
return "please enter valid password";
}
},
onSaved: (String value) {
_formData['password'] = value;
},
decoration: InputDecoration(
labelText: 'Password',
),
);
}
Widget _passwordConfirmTextField() {
return TextFormField(
obscureText: true,
validator: (String value) {
if (value.isEmpty || value.length < 6) {
return "please enter valid password";
}
},
onSaved: (String value) {
_formData['password'] = value;
},
decoration: InputDecoration(
labelText: 'Password',
),
);
}
void _submitForm() {
if (!_formKey.currentState.validate()) {
return;
}
_formKey.currentState.save();
print(_formData);
Navigator.of(context).pushNamed('/home');
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Image(
image: AssetImage("assets2/car.jpg"),
fit: BoxFit.cover,
color: Colors.black87,
colorBlendMode: BlendMode.darken,
),
SingleChildScrollView(
child: Form(
key: _formKey,
child: Container(
width: double.infinity,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 80.0),
child: Logo(),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 8.0, bottom: 80.0),
child: Text(
"Airbnb",
style: TextStyle(fontSize: 30.0),
),
),
],
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: _emailTextField()),
SizedBox(
height: 15.0,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: _passwordTextField()),
Row(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 5.0, top: 10.0),
child: GestureDetector(
onTap: () {
_submitForm();
},
child: Container(
alignment: Alignment.center,
height: 60.0,
decoration: BoxDecoration(
color: Color(0xFF18D191),
borderRadius: BorderRadius.circular(10.0)),
child: Text(
'login',
style: TextStyle(
fontSize: 20.0, color: Colors.white),
),
),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(
left: 10.0, right: 20.0, top: 10.0),
child: Container(
alignment: Alignment.center,
height: 70.0,
child: Text(
'Forgot Password?',
style: TextStyle(
fontSize: 15.0, color: Color(0xFF18D191)),
),
),
),
),
],
),
Column(
children: <Widget>[
Container(
child: Text("switch to sign up"),
alignment: Alignment.bottomCenter,
),