Register screen check if textboxes are empty - flutter

Hello guys i am trying to check if the input fields for my register screen are empty and give an error message for each one if any is empty.
I added the text editing controllers and the booleans for if each box is empty or not.
Then on button press it checks if there is no text in any of the fields and should display the error message for each of the field.
Right now it tells me that the text provided in this "errorText: _emptyboxmail ? 'field cannot be empty' : null," is dead code for each one.
If i change the boolean to true then it shows that null is dead code in code i gave above.
How do i make this work without having dead code? The program runs as usual it just not show me the error message if i leave the boxes empty
import 'package:club_mark_2/styles/style.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'userPreferences/user_details_preference.dart';
class RegisterScreen extends StatefulWidget {
const RegisterScreen({Key? key}) : super(key: key);
#override
_RegisterScreenState createState() => _RegisterScreenState();
}
class _RegisterScreenState extends State<RegisterScreen> {
#override
Widget build(BuildContext context) {
final registerEmail = TextEditingController();
final registerPassword = TextEditingController();
final verifyPassword = TextEditingController();
final registerName = TextEditingController();
bool _emptyboxmail = false;
bool _emptyboxpass = false;
bool _emptyboxverify = false;
bool _emptyboxregistername = false;
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
#override
void dispose() {
// Clean up the controller when the widget is disposed.
registerEmail.dispose();
registerPassword.dispose();
verifyPassword.dispose();
registerName.dispose();
super.dispose();
}
return Scaffold(
backgroundColor: Colors.transparent,
body: SizedBox(
width: width,
height: height,
child: Stack(children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 15, top: 165, right: 15),
child: ListView(
children: [
Center(
child: Text(
'SIGN UP',
style: TextStyle(
color: Colors.white,
fontSize: 30.0,
fontWeight: FontWeight.bold,
fontFamily: 'Montserrat',
),
),
),
Container(
padding: EdgeInsets.all(8.0),
child: TextFormField(
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
errorText: _emptyboxregistername
? 'field cannot be empty'
: null,
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.grey.withOpacity(0.5)),
borderRadius: BorderRadius.circular(20)),
hintText: 'Full Name',
hintStyle: TextStyle(color: kcMediumGreyColor),
labelStyle: TextStyle(color: Colors.white),
prefixIcon: const Icon(
Icons.person,
color: Colors.white,
),
),
controller: registerName,
),
),
SizedBox(
height: 5,
),
Container(
padding: EdgeInsets.all(8.0),
child: TextFormField(
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
errorText: _emptyboxmail ? 'field cannot be empty' : null,
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.grey.withOpacity(0.5)),
borderRadius: BorderRadius.circular(20),
),
hintText: 'E-mail',
hintStyle: TextStyle(color: kcMediumGreyColor),
labelStyle: TextStyle(color: Colors.white),
prefixIcon: const Icon(
Icons.email,
color: Colors.white,
),
),
controller: registerEmail,
),
),
SizedBox(
height: 5,
),
Container(
padding: EdgeInsets.all(8.0),
child: TextFormField(
style: TextStyle(color: Colors.white),
obscureText: true,
decoration: InputDecoration(
errorText: _emptyboxpass ? 'field cannot be empty' : null,
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.grey.withOpacity(0.5)),
borderRadius: BorderRadius.circular(20),
),
hintText: 'Password',
hintStyle: TextStyle(color: kcMediumGreyColor),
labelStyle: TextStyle(
color: Colors.white,
),
prefixIcon: const Icon(
Icons.lock,
color: Colors.white,
),
),
controller: registerPassword,
),
),
SizedBox(
height: 5,
),
//VERIFY PASSWORD TEXT BOX
Container(
padding: EdgeInsets.all(8.0),
child: TextFormField(
style: TextStyle(color: Colors.white),
obscureText: true,
decoration: InputDecoration(
errorText:
_emptyboxverify ? 'field cannot be empty' : null,
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.grey.withOpacity(0.5)),
borderRadius: BorderRadius.circular(20),
),
hintText: 'Verify Password',
hintStyle: TextStyle(color: kcMediumGreyColor),
labelStyle: TextStyle(color: Colors.white),
prefixIcon: const Icon(
Icons.lock,
color: Colors.white,
),
),
//TEXT EDITING CONTROLLER
controller: verifyPassword,
),
),
SizedBox(
height: 20,
),
SizedBox(
height: 60,
child: TextButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
),
),
),
// THE BUTTON THAT CHECKS IF THE BOOLEANS ARE TRUE OR FALSE FOR THE TEXT BEING EMPTY
onPressed: () {
registerEmail.text.isEmpty
? _emptyboxmail = true
: _emptyboxmail = false;
registerName.text.isEmpty
? _emptyboxregistername = true
: _emptyboxregistername = false;
registerPassword.text.isEmpty
? _emptyboxpass = true
: _emptyboxpass = false;
verifyPassword.text.isEmpty
? _emptyboxverify = true
: _emptyboxverify = false;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UserDetailsPreference(),
),
);
},
child: Text('Sign Up'),
),
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.all(8.0),
child: Text(
"━━━━━ OR SIGN UP WITH ━━━━━",
style: TextStyle(color: kcMediumGreyColor),
),
),
],
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {},
child: Container(
decoration: BoxDecoration(),
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Image.asset('lib/assets/images/googleIcon.png',
width: 50.0, height: 50.0),
),
),
),
SizedBox(
width: 30,
),
InkWell(
onTap: () {},
child: Container(
decoration: BoxDecoration(),
child: ClipRRect(
// borderRadius: BorderRadius.circular(20.0),
child: Image.asset(
'lib/assets/images/facebookIcon.png',
width: 45.0,
height: 45.0),
),
),
),
],
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.all(8.0),
child: Text(
"Already have an account?",
style: TextStyle(color: Colors.white),
),
),
Text(
"SIGN IN",
style: TextStyle(color: kcPrimaryColor),
),
],
),
],
),
),
]),
),
);
}
}

You have to move all your initializations and dispose method out of build method.
class _RegisterScreenState extends State<RegisterScreen> {
final registerEmail = TextEditingController();
final registerPassword = TextEditingController();
final verifyPassword = TextEditingController();
final registerName = TextEditingController();
bool _emptyboxmail = false;
bool _emptyboxpass = false;
bool _emptyboxverify = false;
bool _emptyboxregistername = false;
#override
void dispose() {
// Clean up the controller when the widget is disposed.
registerEmail.dispose();
registerPassword.dispose();
verifyPassword.dispose();
registerName.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
return Scaffold(
backgroundColor: Colors.transparent,
body: SizedBox(
width: width,
height: height,
// ... rest of your code

Create a Form with a GlobalKey
Add a TextFormField with validation logic
Create a button to validate and submit the form
https://flutter.dev/docs/cookbook/forms/validation

Related

How to create a new instance of MobX and override the old instance using MobX with Provider?

I'm new developing with Flutter. I'm now using MobX to manage my app states and using Provider to pass the instance of my MobX Controller through screens.
The app is simple, where the user go through the screens answering the questions. Everytime a question is answered, the answer is saved on the MobX Controller. Everytime the user go to the next screen or return to the previous screen, if the field has an answer, the MobX Controller fill that answer. So, if the user return to the Main screen and start to answer the questions again, he will start where he stoped. All is working until the end of the questions.
When the user finish the answers, all the data is saved to Firebase and I need to "restart" the MobX Controller. But when I create a new instance of the MobX Controller and pass it to the older instance, the Provider insist in keep the old instance, with all the old answers.
I've tried a lot of things, and the only and incorrect way to make it works, was changing every variable of the class manually. And this is so sad, because is too much fields.
So, the question is: How can I create a new instance of my MobX Controller and make the Provider use this new instance?
Principal.dart: (the main screen of app)
void main() {
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
runApp(
MultiProvider(
providers: [
Provider<Controller>(
create: (BuildContext context) => Controller(),
)
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.black
),
home: Main(),
),
)
);
}
class Main extends StatefulWidget {
const Main({Key? key}) : super(key: key);
#override
State<Main> createState() => _MainState();
}
class _MainState extends State<Main> {
Controller controller_mobx = Controller();
int _conexao = 0; // 0 - SEM CONEXAO | 1 - CONECTADO
#override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
controller_mobx = Provider.of(context);
}
#override
void initState() {
// TODO: implement initState
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp
]);
}
#override
Widget build(BuildContext context) {
Util cores = Util();
verificar_conexao();
double altura_imagem =MediaQuery.of(context).size.height/5;
controller_mobx.preenche_lista_vistoria();
FlutterNativeSplash.remove();
return Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/wallpaper.png'),
//colorFilter: ColorFilter.mode(Colors.white.withOpacity(0.75), BlendMode.modulate,),
fit: BoxFit.cover
)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
height: altura_imagem,
child: Image.asset("images/logo.png"),
),
Padding(
padding: EdgeInsets.only(top: 16, bottom: 8),
child: Container(
height: 50,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.all(Radius.circular(15)),
border: Border.all(
color: cores.laranja_teccel,
width: 2
),
),
child: Material(
borderRadius: BorderRadius.all(Radius.circular(15)),
child: InkWell(
splashColor: cores.laranja_teccel.withOpacity(0.25),
hoverColor: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(12)),
onTap: (){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NovaVistoria()
)
);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding:EdgeInsets.only(left: 4),
child: Icon(
Icons.directions_car_rounded,
color: cores.cor_app_bar,
size: 30,
),
),
Align(
alignment: Alignment.center,
child: Text(
"Nova Vistoria",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 14,
),
),
),
Padding(
padding:EdgeInsets.only(right: 4),
child: Icon(
Icons.directions_car_rounded,
color: cores.cor_app_bar,
size: 30,
),
),
],
)
),
)
)
),
],
),
)
],
),
);
}
verificar_conexao() async{
Util verif = Util();
_conexao = await verif.verificar_conexao();
if(_conexao == 0){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SemConexao()
)
);
}
else{
return;
}
}
}
NovaVistoria.dart: (the screen used to manage each tab of questions on app)
class NovaVistoria extends StatefulWidget {
#override
State<NovaVistoria> createState() => _NovaVistoriaState();
}
class _NovaVistoriaState extends State<NovaVistoria> {
Controller controller_mobx = Controller();
#override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
controller_mobx = Provider.of(context);
}
Util cores = Util();
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/wallpaper.png'),
//colorFilter: ColorFilter.mode(Colors.white.withOpacity(0.75), BlendMode.modulate,),
fit: BoxFit.cover
)
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: PreferredSize(
preferredSize: Size.fromHeight(50),
child: AppBar(
title: Text('Nova Vistoria', style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white),),
backgroundColor: cores.cor_app_bar,
automaticallyImplyLeading: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
bottom: Radius.circular(10),
),
),
),
),
body: Observer(
builder: (_){
return Padding(
padding: EdgeInsets.all(8),
child: controller_mobx.abas[controller_mobx.indice_tela]
);
},
)
),
);
}
}
AbaDados.dart: (the first tab of questions)
class AbaDados extends StatefulWidget {
const AbaDados({Key? key}) : super(key: key);
#override
State<AbaDados> createState() => _AbaDadosState();
}
class _AbaDadosState extends State<AbaDados> {
Controller controller_mobx = Controller();
#override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
controller_mobx = Provider.of(context);
}
#override
Widget build(BuildContext context) {
DateTime now = DateTime.now();
String data_relatorio = DateFormat('dd/MM/yyyy kk:mm:ss').format(now);
if(controller_mobx.data.isEmpty)
_controller_data.text = data_relatorio;
else
_controller_data.text = controller_mobx.data;
_controller_vistoriador.text = controller_mobx.vistoriador;
_controller_condutor.text = controller_mobx.condutor;
_controller_modelo.text = controller_mobx.modelo_veiculo;
_controller_placa.text = controller_mobx.placa;
return Observer(
builder: (_){
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Text(
"1 - Dados da Vistoria",
style: TextStyle(
color: cores.laranja_teccel,
fontSize: 24,
fontWeight: FontWeight.bold
),
)
)
]
),
),
Padding(
padding: EdgeInsets.only(top: 8, bottom: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Container(
height: 50,
child: TextField(
enabled: false,
controller: _controller_data,
keyboardType: TextInputType.name,
textCapitalization: TextCapitalization.characters,
textInputAction: TextInputAction.next,
cursorColor: cores.cor_app_bar,
style: TextStyle(
color: cores.cor_app_bar,
fontSize: 14,
fontWeight: FontWeight.bold
),
decoration: InputDecoration(
floatingLabelBehavior: FloatingLabelBehavior.always,
counterText: "",
labelText: "Data da Vistoria",
labelStyle: TextStyle(color: cores.laranja_teccel, fontWeight: FontWeight.normal),
fillColor: Colors.transparent,
hoverColor: cores.cor_app_bar,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(width: 2, color: cores.cor_app_bar),
borderRadius: BorderRadius.circular(15),
),
disabledBorder: OutlineInputBorder(
borderSide: BorderSide(width: 2, color: cores.cor_app_bar),
borderRadius: BorderRadius.circular(15),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(width: 2, color: cores.laranja_teccel),
borderRadius: BorderRadius.circular(15),
),
),
onSubmitted: (content){
},
),
),
)
]
),
),
Padding(
padding: EdgeInsets.only(top: 8, bottom: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Container(
height: 50,
child: TextField(
controller: _controller_vistoriador,
focusNode: _foco_vistoriador,
keyboardType: TextInputType.name,
textCapitalization: TextCapitalization.characters,
textInputAction: TextInputAction.next,
cursorColor: cores.cor_app_bar,
style: TextStyle(
color: cores.cor_app_bar,
fontSize: 14,
fontWeight: FontWeight.bold
),
decoration: InputDecoration(
floatingLabelBehavior: FloatingLabelBehavior.always,
counterText: "",
labelText: "Vistoriador",
labelStyle: TextStyle(color: cores.laranja_teccel, fontWeight: FontWeight.normal),
fillColor: Colors.transparent,
hoverColor: cores.cor_app_bar,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(width: 2, color: cores.cor_app_bar),
borderRadius: BorderRadius.circular(15),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(width: 2, color: cores.laranja_teccel),
borderRadius: BorderRadius.circular(15),
),
),
onSubmitted: (content){
},
),
),
)
]
),
),
Padding(
padding: EdgeInsets.only(top: 8, bottom: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Container(
height: 50,
child: TextField(
controller: _controller_condutor,
focusNode: _foco_condutor,
keyboardType: TextInputType.name,
textCapitalization: TextCapitalization.characters,
textInputAction: TextInputAction.next,
cursorColor: cores.cor_app_bar,
style: TextStyle(
color: cores.cor_app_bar,
fontSize: 14,
fontWeight: FontWeight.bold
),
decoration: InputDecoration(
floatingLabelBehavior: FloatingLabelBehavior.always,
counterText: "",
labelText: "Condutor",
labelStyle: TextStyle(color: cores.laranja_teccel, fontWeight: FontWeight.normal),
fillColor: Colors.transparent,
hoverColor: cores.cor_app_bar,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(width: 2, color: cores.cor_app_bar),
borderRadius: BorderRadius.circular(15),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(width: 2, color: cores.laranja_teccel),
borderRadius: BorderRadius.circular(15),
),
),
onSubmitted: (content){
},
),
),
)
]
),
),
Padding(
padding: EdgeInsets.only(top: 8, bottom: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Container(
height: 50,
child: TextField(
controller: _controller_modelo,
focusNode: _foco_modelo,
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.characters,
textInputAction: TextInputAction.next,
cursorColor: cores.cor_app_bar,
style: TextStyle(
color: cores.cor_app_bar,
fontSize: 14,
fontWeight: FontWeight.bold
),
decoration: InputDecoration(
floatingLabelBehavior: FloatingLabelBehavior.always,
counterText: "",
labelText: "Modelo do Veículo",
labelStyle: TextStyle(color: cores.laranja_teccel, fontWeight: FontWeight.normal),
fillColor: Colors.transparent,
hoverColor: cores.cor_app_bar,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(width: 2, color: cores.cor_app_bar),
borderRadius: BorderRadius.circular(15),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(width: 2, color: cores.laranja_teccel),
borderRadius: BorderRadius.circular(15),
),
),
onSubmitted: (content){
},
),
),
)
]
),
),
Padding(
padding: EdgeInsets.only(top: 8, bottom: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Container(
height: 50,
child: TextField(
controller: _controller_placa,
focusNode: _foco_placa,
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.characters,
textInputAction: TextInputAction.done,
cursorColor: cores.cor_app_bar,
style: TextStyle(
color: cores.cor_app_bar,
fontSize: 14,
fontWeight: FontWeight.bold
),
decoration: InputDecoration(
floatingLabelBehavior: FloatingLabelBehavior.always,
counterText: "",
labelText: "Placa",
labelStyle: TextStyle(color: cores.laranja_teccel, fontWeight: FontWeight.normal),
fillColor: Colors.transparent,
hoverColor: cores.cor_app_bar,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(width: 2, color: cores.cor_app_bar),
borderRadius: BorderRadius.circular(15),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(width: 2, color: cores.laranja_teccel),
borderRadius: BorderRadius.circular(15),
),
),
),
),
)
]
),
),
Expanded(child: Container()),
Padding(
padding: EdgeInsets.only(top: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: Container(
height: 50,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.all(Radius.circular(15)),
border: Border.all(
color: cores.laranja_teccel,
width: 2
),
),
child: Material(
borderRadius: BorderRadius.all(Radius.circular(15)),
child: InkWell(
splashColor: cores.laranja_teccel.withOpacity(0.25),
hoverColor: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(12)),
onTap: (){
salvar_dados();
},
child: Align(
alignment: Alignment.center,
child: Text(
"Avançar",
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 14,
),
),
),
),
)
),
)
]
),
),
],
);
},
);
}
salvar_dados(){
if(_controller_vistoriador.text.isEmpty || _controller_condutor.text.isEmpty ||
_controller_modelo.text.isEmpty || _controller_placa.text.isEmpty){
final snackBar = SnackBar(
content: const Text('Existem campos obrigatórios não preenchidos. Verifique e tente novamente'),
backgroundColor: cores.cor_accent,
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
else{
controller_mobx.salvar_dados_iniciais(_controller_data.text, _controller_vistoriador.text, _controller_condutor.text, _controller_modelo.text, _controller_placa.text);
Controller controller_novo = Controller();
controller_mobx = controller_novo;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Main()
)
);
}
}
For this question, I changed the lenght of the app, so it finishes on the first tab. On the last rows, we save the data, create a new instance of controller_mobx and then return to the main screen.
Where I'm creating a new Controller instance:
Controller controller_novo = Controller();
controller_mobx = controller_novo;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Main()
)
);
So, after we finish and return to the Main Screen, the Controller must be without data. But when we start to answer the questions again, the fields are filled with the old answers. On the gif below I show the problem:
problem
Any help will be appreciate. Please, explain in details for best understanding.
How it should work:
what I need
What I needed to do to make it work:
[...]
#observable
bool vistoria_finalizada = false;
#action
alterar_vistoria_finalizada(bool valor){
vistoria_finalizada = valor;
if(valor){
data = "";
vistoriador = "";
condutor = "";
modelo_veiculo = "";
placa = "";
}
}
[...]

Flutter SingleChildScrollView Sign Up Screen not working

I am trying to create a scrollable sign up screen for when the keyboard pops up but my SingleChildScrollView widget doesn't seem to be working. I don't know whether this has to do with its placement in the stack or the inner column but help would be much appreciated. I've tried a ListView instead of a column, using the Expanded widget around the SingleChildScrollView but to no success.
Sign Up Screen
Sign Up Screen with Keyboard
An example to copy and run here.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const SignUpScreen(),
);
}
}
class SignUpScreen extends StatefulWidget {
const SignUpScreen({Key? key}) : super(key: key);
#override
_SignUpScreenState createState() => _SignUpScreenState();
}
class _SignUpScreenState extends State<SignUpScreen> {
final _formKey = GlobalKey<FormState>();
bool _obscurePassword = true;
Color _obscureColor = Colors.grey;
InputDecoration textFormFieldDecoration = InputDecoration(
filled: true,
fillColor: const Color(0xFFF5F5F5),
prefixIcon: const Padding(
padding: EdgeInsets.symmetric(horizontal: 20),
child: Icon(
Icons.email,
color: Colors.blueAccent,
size: 26,
),
),
suffixIcon: null,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(color: Colors.white),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(color: Colors.white),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: const BorderSide(color: Colors.white),
),
hintText: 'E-mail',
hintStyle: const TextStyle(
fontFamily: 'OpenSans',
fontSize: 18,
),
);
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
// Shows circular progress indicator while loading
body:
// A stack lays items over one another.
Stack(
children: [
//The SizedBox provides the colored rounded aesthetic card behind the login.
SizedBox(
height: MediaQuery.of(context).size.height * 0.7,
child: Container(
color: Colors.redAccent,
),
),
Form(
key: _formKey,
child: Column(
// Keeps things in the center vertically
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// Builds App Logo
Row(
// Keeps things in the center horizontally.
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text(
'Heart',
style: TextStyle(
fontSize: 34,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
Text(
'by AHG',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
],
),
const SizedBox(height: 30),
// Build sign up container card.
ClipRRect(
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
child: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height * 0.65,
width: MediaQuery.of(context).size.width * 0.85,
color: Colors.white,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//Sign Up / Login Text
const Text(
'Sign Up',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.w700,
color: Colors.black,
),
),
const SizedBox(height: 25),
// Email form field
TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: textFormFieldDecoration.copyWith(
prefixIcon: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20),
child: Icon(
Icons.email,
color: Theme.of(context)
.colorScheme
.secondary,
size: 26,
),
),
hintText: 'E-mail'),
autocorrect: false,
),
const SizedBox(height: 13),
// Build password form field
TextFormField(
obscureText: _obscurePassword,
keyboardType: TextInputType.text,
decoration: textFormFieldDecoration.copyWith(
prefixIcon: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20),
child: Icon(
Icons.lock,
color: Theme.of(context)
.colorScheme
.secondary,
size: 26,
),
),
suffixIcon: Padding(
padding: const EdgeInsets.only(right: 25),
child: IconButton(
icon: const Icon(
Icons.remove_red_eye_rounded),
color: _obscureColor,
iconSize: 23,
onPressed: () {
setState(() {
_obscurePassword =
!_obscurePassword;
_obscureColor == Colors.grey
? _obscureColor =
Theme.of(context)
.colorScheme
.secondary
: _obscureColor = Colors.grey;
});
},
),
),
hintText: 'Password'),
autocorrect: false,
),
const SizedBox(height: 13),
// Build confirm password form field
TextFormField(
obscureText: _obscurePassword,
keyboardType: TextInputType.text,
decoration: textFormFieldDecoration.copyWith(
prefixIcon: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20),
child: Icon(
Icons.lock,
color: Theme.of(context)
.colorScheme
.secondary,
size: 26,
),
),
suffixIcon: Padding(
padding: const EdgeInsets.only(right: 25),
child: IconButton(
icon: const Icon(
Icons.remove_red_eye_rounded),
color: _obscureColor,
iconSize: 23,
onPressed: () {
setState(() {
_obscurePassword =
!_obscurePassword;
_obscureColor == Colors.grey
? _obscureColor =
Theme.of(context)
.colorScheme
.secondary
: _obscureColor = Colors.grey;
});
},
),
),
hintText: 'Confirm'),
autocorrect: false,
),
// Login Button
const SizedBox(
height: 30,
),
SizedBox(
height: 1.4 *
(MediaQuery.of(context).size.height / 20),
width: 5 *
(MediaQuery.of(context).size.width / 10),
child: ElevatedButton(
child: const Text('Sign Up'),
onPressed: _validateInputs,
),
),
],
),
),
),
),
),
//Sign Up Text
const SizedBox(
height: 20,
),
TextButton(
onPressed: () {},
child: RichText(
text: TextSpan(children: [
TextSpan(
text: 'Don\'t have an account?',
style: TextStyle(
color: Colors.black,
fontSize: MediaQuery.of(context).size.height / 40,
fontWeight: FontWeight.w400,
),
),
TextSpan(
text: ' Login',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
fontSize: MediaQuery.of(context).size.height / 40,
fontWeight: FontWeight.bold,
),
)
]),
),
),
],
),
)
],
),
),
);
}
void _validateInputs() {
if (_formKey.currentState?.validate() != null) {
final _validForm = _formKey.currentState!.validate();
if (_validForm) {
_formKey.currentState!.save();
}
}
}
}
Change resizeToAvoidBottomInset to true
put SingleChildScrollView before Stack
Like this
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: true,
body: SingleChildScrollView(...)
Put the SingleChildScrollView as the Scaffold's body.
Scaffold(
resizeToAvoidBottomInset: true,
body:
SingleChildScrollView(child: ...)
)

Flutter TextField hide by Keyboard

I'm a beginner in the flutter, I have a conflict, when I'm focusing on a TexFiled, the keyboard hidden over the TextField, and bottom button not showing i attached my conflict here
any solution for this
Thanks
code here
import 'dart:ui';
import 'package:crapp/pages/create_password/password_screen.dart';
import 'package:crapp/widgets/components/alert.dart';
import 'package:crapp/widgets/components/page_animation.dart';
import 'package:crapp/widgets/theme/constants.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:crapp/provider/theme_provider.dart';
class PasswordScreen extends StatefulWidget {
#override
_PasswordScreenState createState() => _PasswordScreenState();
}
class _PasswordScreenState extends State< PasswordScreen > {
final _controller = TextEditingController();
//validation controller
TextEditingController sQuastionController = new TextEditingController();
TextEditingController answerQController = new TextEditingController();
TextEditingController passController = new TextEditingController();
TextEditingController conPassController = new TextEditingController();
final TextEditingController _pass = TextEditingController();
final TextEditingController _confirmPass = TextEditingController();
bool _isButtonEnabled = false;
//final _controller = TextEditingController();
bool isConfirm=false;
check (BuildContext context){
if(sQuastionController.text.isNotEmpty &&
answerQController.text.isNotEmpty &&
conPassController.text.isNotEmpty &&
passController.text.isNotEmpty){
setState(() {
_isButtonEnabled = true;
});
} else {
setState(() {
_isButtonEnabled = false;
});
}
}
checks (BuildContext context){
if(passController.text.isEmpty){
showDialog<void>(
context: context,
builder: (BuildContext dialogContext) {
return Alert(title: "Alert !!!",subTile: "Password must be 10 characters !",);
}
);
}else if(passController.text.length > 0 && passController.text.length < 10){
isConfirm = true;
showDialog<void>(
context: context,
builder: (BuildContext dialogContext) {
return Alert(title: "Alert !!!",subTile: "Password doesn't match !",);
}
);
}
}
checkChanged(){
if( secretVal != null
)
{
setState(() {
isSave = true;
});
}else{
isSave =false;
}
} bool isSave=false;
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
/* double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;*/
Provider.of<ThemeProvider>(context).themeMode == ThemeMode.dark
? 'DarkTheme'
: 'LightTheme';
return Scaffold(
resizeToAvoidBottomInset: false,
body: SafeArea(
child: Column(
children: <Widget>[
Expanded(
child: _signUp(),
),
],
),
), bottomNavigationBar: BottomAppBar(
elevation: 4,
child: Container(
height: 70,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Row(
children: [
Expanded(
child: MaterialButton(
height: 44,
onPressed: () {
FocusScope.of(context).requestFocus(FocusNode());
//check();
},
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(4)),
color: Color(0xFF2A3476),
elevation: 0,
highlightElevation: 0,
child: Container(
child: Text(
"Save",
style: TextStyle(
color: Color(0xFF2A3476),
fontSize: 15,
fontFamily: 'medium'),
),
),
),
),
],
),
),
),
),
/* bottomNavigationBar: Container(
padding: EdgeInsets.all(25.0),
decoration: BoxDecoration(color: Colors.white,
),
child: Row(
children: [
Expanded(
child: MaterialButton(
height: 44,
onPressed: () {
FocusScope.of(context).requestFocus(FocusNode());
*//* Navigator.push(context, SlidePageRoute(page:PasswordScreen()));*//*
},
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
color: _isButtonEnabled ? Color(0xFF2A3476) : Color(0x201E1E99),
elevation: 0,
highlightElevation: 0,
child: Container(
child: Text(
"Next",
style: TextStyle(color: m_fillColor,fontSize: 18,fontWeight: FontWeight.w600 ,
fontFamily: "regular",),
),
),
),
),
],
),
)*/
);
}
Widget _signUp() {
return Container(
constraints: BoxConstraints.expand(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xFF2A3476),
Color(0xFF2A3476),
],
begin: Alignment.topLeft,
end: Alignment.centerRight,
),
),
child: Form(
key: formKey,
child: Container(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding:
const EdgeInsets.symmetric(vertical: 36.0, horizontal: 24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Create Password",
style: TextStyle(
color: Colors.white,
fontSize: 30.0,fontFamily: "medium",
fontWeight: FontWeight.w800,
),
),
],
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30),
),
),
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Steps to set your",
style: TextStyle(
fontSize: 22,
fontFamily: "regular",
fontWeight: FontWeight.w300,
color: Colors.black,
),
),
Text(
"password",
style: TextStyle(
fontSize: 22,
fontFamily: "regular",
fontWeight: FontWeight.w300,
color: Colors.black,
),
),
SizedBox(
height: 20.0,
), Text(
'Secret Question',
style:
TextStyle( fontSize: 15,
fontFamily: "regular",),
), SizedBox(
height: 8.0,
),
Row(
children: [
Expanded(child: InkWell(
onTap: (){
FocusScope.of(context).requestFocus(FocusNode());
secretDialogue();
},
child: Stack(
children: <Widget>[
TextField(
/* textInputAction: TextInputAction.next,*/
controller: sQuastionController,
enabled: false,
onChanged: (val) {
check(context);
},
decoration: InputDecoration(
labelText: secretVal==null?"Select One":secretVal,
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "",
/* prefixIcon: Icon(
Icons.people_outline_rounded,
color: Colors.grey[600],
)*/
),
),
Positioned.directional(
textDirection: Directionality.of(context),
end: 0,
top: 0,
bottom: 0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child:Image.asset(
"assets/icons/ic_drop_arrow.png",
scale: 9,
)),
)
],
),
),
),
],
),
SizedBox(
height: 20.0,
),
Text(
'Answer',
style:
TextStyle( fontSize: 15,
fontFamily: "regular",),
),
SizedBox(
height: 8.0,
),
TextField(
/* keyboardType: TextInputType.emailAddress,*/
/* textInputAction: TextInputAction.next,*/
controller: answerQController,
onChanged: (val){
check(context);
},
decoration: InputDecoration(
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "",
/*prefixIcon: Icon(
Icons.people_outline_rounded,
color: Color(0xFFE1E8F7),
)*/),
),
SizedBox(
height: 20.0,
),
Text(
'Password',
style:
TextStyle( fontSize: 15,
fontFamily: "regular",),
),
SizedBox(
height: 8.0,
),
TextFormField(
/* keyboardType: TextInputType.emailAddress,*/
/* textInputAction: TextInputAction.next,*/
controller: passController,
onChanged: (val){
check(context);
},
//password validation
/* validator: (val){
if(val!.isEmpty)
return 'Empty';
return null;
},*/
decoration: InputDecoration(
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "************",
),
),
SizedBox(
height: 20.0,
),
Text(
'Confirm Password',
style:
TextStyle( fontSize: 15,
fontFamily: "regular",),
),
SizedBox(
height: 8.0,
),
TextFormField(
textInputAction: TextInputAction.done,
controller: conPassController,
onChanged: (val){
check(context);
},
//password validation
/* validator: (val){
if(val!.isEmpty)
return 'Empty';
if(val != _pass.text)
return 'Not Match';
return null;
},*/
decoration: InputDecoration(
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "************",
),
),
SizedBox(
height: 20.0,
),
SizedBox(
height: 8.0,
),
SizedBox(
height:200.0,
),
],
),
),
),
],
),
),
),
),
);
}
//
//Secret Qu Alert
List secretList =[
"-What’s your favorite team?",
"-What’s your astrological sign?",
"-What’s your favorite movie?",
"-What city were you born in?",
"-What was your first car?",
];
var secretVal;
void secretDialogue(){
showDialog<void>(
context: context,
// false = user must tap button, true = tap outside dialog
builder: (BuildContext dialogContext) {
return StatefulBuilder(
builder: (context,setState){
return Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
insetPadding: EdgeInsets.all(20),
child: Container(
padding: EdgeInsets.symmetric(vertical: 10),
child: Column(
mainAxisSize: MainAxisSize.min,
children: List.generate(secretList.length, (index){
return InkWell(
onTap: (){
setState(() {
secretVal = secretList[index];
Navigator.pop(context);
});
},
child: Container(
height: 50,
padding: EdgeInsets.symmetric(horizontal: 20),
alignment: Alignment.centerLeft,
child: Text(secretList[index],
style: TextStyle(
fontSize: 18,
fontFamily: "medium",
),),
),
);
})
),
),
);
}
);
},
);
}
}
Wrap your Column by SingleChildScrollView. It will solve your problem.
like this..
body: SafeArea(
child: SingleChildScrollView(
child: Column(
Also I think after this there is no need of
resizeToAvoidBottomInset: false,
in Scaffold.
Please check out and I have found some inconsistency in code, refactored some of them
import 'dart:ui';
import 'package:crapp/pages/create_password/password_screen.dart';
import 'package:crapp/widgets/components/alert.dart';
import 'package:crapp/widgets/components/page_animation.dart';
import 'package:crapp/widgets/theme/constants.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:crapp/provider/theme_provider.dart';
class PasswordScreen extends StatefulWidget {
#override
_PasswordScreenState createState() => _PasswordScreenState();
}
class _PasswordScreenState extends State< PasswordScreen > {
final _controller = TextEditingController();
//validation controller
TextEditingController sQuastionController = new TextEditingController();
TextEditingController answerQController = new TextEditingController();
TextEditingController passController = new TextEditingController();
TextEditingController conPassController = new TextEditingController();
final TextEditingController _pass = TextEditingController();
final TextEditingController _confirmPass = TextEditingController();
bool _isButtonEnabled = false;
//final _controller = TextEditingController();
bool isConfirm = false;
check(BuildContext context) {
if (sQuastionController.text.isNotEmpty &&
answerQController.text.isNotEmpty &&
conPassController.text.isNotEmpty &&
passController.text.isNotEmpty) {
setState(() {
_isButtonEnabled = true;
});
} else {
setState(() {
_isButtonEnabled = false;
});
}
}
void initState() {
SystemChannels.textInput.invokeMethod('TextInput.hide');
super.initState();
}
checks (BuildContext context){
if(passController.text.isEmpty){
showDialog<void>(
context: context,
builder: (BuildContext dialogContext) {
return Alert(title: "Alert !!!",subTile: "Password must be 10 characters !",);
}
);
}else if(passController.text.length > 0 && passController.text.length < 10){
isConfirm = true;
showDialog<void>(
context: context,
builder: (BuildContext dialogContext) {
return Alert(title: "Alert !!!",subTile: "Password doesn't match !",);
}
);
}
}
checkChanged() {
if (secretVal != null) {
setState(() {
isSave = true;
});
} else {
isSave = false;
}
}
bool isSave = false;
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
/* double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;*/
Provider.of<ThemeProvider>(context).themeMode == ThemeMode.dark
? 'DarkTheme'
: 'LightTheme';
return Scaffold(
// resizeToAvoidBottomInset: false,
body: _signUp(),
bottomNavigationBar: BottomAppBar(
elevation: 4,
child: Container(
height: 70,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Row(
children: [
Expanded(
child: MaterialButton(
height: 44,
onPressed: () {
FocusScope.of(context).requestFocus(FocusNode());
//check();
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4)),
color: Color(0xFF2A3476),
elevation: 0,
highlightElevation: 0,
child: Container(
child: Text(
"Save",
style: TextStyle(
color: Color(0xFF2A3476),
fontSize: 15,
fontFamily: 'medium'),
),
),
),
),
],
),
),
),
),
/* bottomNavigationBar: Container(
padding: EdgeInsets.all(25.0),
decoration: BoxDecoration(color: Colors.white,
),
child: Row(
children: [
Expanded(
child: MaterialButton(
height: 44,
onPressed: () {
FocusScope.of(context).requestFocus(FocusNode());
*/ /* Navigator.push(context, SlidePageRoute(page:PasswordScreen()));*/ /*
},
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
color: _isButtonEnabled ? Color(0xFF2A3476) : Color(0x201E1E99),
elevation: 0,
highlightElevation: 0,
child: Container(
child: Text(
"Next",
style: TextStyle(color: m_fillColor,fontSize: 18,fontWeight: FontWeight.w600 ,
fontFamily: "regular",),
),
),
),
),
],
),
)*/
);
}
Widget _signUp() {
return Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xFF2A3476),
Color(0xFF2A3476),
],
begin: Alignment.topLeft,
end: Alignment.centerRight,
),
),
child: SingleChildScrollView(
child: Form(
key: formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(
vertical: 36.0, horizontal: 24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Create Password",
style: TextStyle(
color: Colors.white,
fontSize: 30.0,
fontFamily: "medium",
fontWeight: FontWeight.w800,
),
),
],
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30),
),
),
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Steps to set your",
style: TextStyle(
fontSize: 22,
fontFamily: "regular",
fontWeight: FontWeight.w300,
color: Colors.black,
),
),
Text(
"password",
style: TextStyle(
fontSize: 22,
fontFamily: "regular",
fontWeight: FontWeight.w300,
color: Colors.black,
),
),
SizedBox(
height: 20.0,
),
Text(
'Secret Question',
style: TextStyle(
fontSize: 15,
fontFamily: "regular",
),
),
SizedBox(
height: 8.0,
),
Row(
children: [
Expanded(
child: InkWell(
onTap: () {
FocusScope.of(context)
.requestFocus(FocusNode());
secretDialogue();
},
child: Stack(
children: <Widget>[
TextField(
/* textInputAction: TextInputAction.next,*/
controller: sQuastionController,
enabled: false,
onChanged: (val) {
check(context);
},
decoration: InputDecoration(
labelText: secretVal == null
? "Select One"
: secretVal,
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "",
/* prefixIcon: Icon(
Icons.people_outline_rounded,
color: Colors.grey[600],
)*/
),
),
Positioned.directional(
textDirection: Directionality.of(context),
end: 0,
top: 0,
bottom: 0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
"assets/icons/ic_drop_arrow.png",
scale: 9,
)),
)
],
),
),
),
],
),
SizedBox(
height: 20.0,
),
Text(
'Answer',
style: TextStyle(
fontSize: 15,
fontFamily: "regular",
),
),
SizedBox(
height: 8.0,
),
GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
},
child: TextField(
/* keyboardType: TextInputType.emailAddress,*/
/* textInputAction: TextInputAction.next,*/
controller: answerQController,
onChanged: (val) {
check(context);
},
decoration: InputDecoration(
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "",
/*prefixIcon: Icon(
Icons.people_outline_rounded,
color: Color(0xFFE1E8F7),
)*/
),
),
),
SizedBox(
height: 20.0,
),
Text(
'Password',
style: TextStyle(
fontSize: 15,
fontFamily: "regular",
),
),
SizedBox(
height: 8.0,
),
GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
},
child: TextFormField(
/* keyboardType: TextInputType.emailAddress,*/
/* textInputAction: TextInputAction.next,*/
controller: passController,
onChanged: (val) {
check(context);
},
//password validation
/* validator: (val){
if(val!.isEmpty)
return 'Empty';
return null;
},*/
decoration: InputDecoration(
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "************",
),
),
),
SizedBox(
height: 20.0,
),
Text(
'Confirm Password',
style: TextStyle(
fontSize: 15,
fontFamily: "regular",
),
),
SizedBox(
height: 8.0,
),
GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
},
child: TextFormField(
textInputAction: TextInputAction.done,
controller: conPassController,
onChanged: (val) {
check(context);
},
//password validation
/* validator: (val){
if(val!.isEmpty)
return 'Empty';
if(val != _pass.text)
return 'Not Match';
return null;
},*/
decoration: InputDecoration(
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "************",
),
),
),
SizedBox(
height: 20.0,
),
SizedBox(
height: 8.0,
),
SizedBox(
height: 200.0,
),
],
),
),
),
],
),
),
),
);
}
//
//Secret Qu Alert
List secretList = [
"-What’s your favorite team?",
"-What’s your astrological sign?",
"-What’s your favorite movie?",
"-What city were you born in?",
"-What was your first car?",
];
var secretVal;
void secretDialogue() {
showDialog<void>(
context: context,
// false = user must tap button, true = tap outside dialog
builder: (BuildContext dialogContext) {
return StatefulBuilder(builder: (context, setState) {
return Dialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
insetPadding: EdgeInsets.all(20),
child: Container(
padding: EdgeInsets.symmetric(vertical: 10),
child: Column(
mainAxisSize: MainAxisSize.min,
children: List.generate(secretList.length, (index) {
return InkWell(
onTap: () {
setState(() {
secretVal = secretList[index];
Navigator.pop(context);
});
},
child: Container(
height: 50,
padding: EdgeInsets.symmetric(horizontal: 20),
alignment: Alignment.centerLeft,
child: Text(
secretList[index],
style: TextStyle(
fontSize: 18,
fontFamily: "medium",
),
),
),
);
})),
),
);
});
},
);
}
}

The method 'validate' was called on null

The Method validate is calling null
How can I fix it?
Here is my code
saveUserInfoToFireStore() async {
final GoogleSignInAccount gCurrentUser = gSignIn.currentUser;
DocumentSnapshot documentSnapshot =
await userRefrence.document(gCurrentUser.id).get();
if (!documentSnapshot.exists) {
final username = await Navigator.push(context,
MaterialPageRoute(builder: (context) => CreateAccountPage()));}
CreateAccountPage.dart
class _CreateAccountPageState extends State<CreateAccountPage> {
final _scaffoldKey = GlobalKey<ScaffoldState>();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
// final _formKey = GlobalKey<FormState>();
String username;
submitUsername() {
final form = _formKey.currentState;
if (form.validate()) {
form.save();
SnackBar snackBar = SnackBar(
content: Text("Welcome" + username),
);
_scaffoldKey.currentState.showSnackBar(snackBar);
Timer(Duration(seconds: 4), () {
Navigator.pop(context, username);
});
}
}
#override
Widget build(BuildContext parentContext) {
return Scaffold(
key: _scaffoldKey,
appBar:
header(context, strTitle: "Settings", disappearedBackButton: true),
body: ListView(
children: <Widget>[
Container(
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 26.0),
child: Center(
child: Text(
"Set up a Username",
style: TextStyle(fontSize: 26.0),
),
),
),
Padding(
padding: EdgeInsets.all(17.0),
child: Container(
child: Form(
key: _formKey,
autovalidate: true,
child: TextFormField(
style: TextStyle(color: Colors.white),
validator: (val) {
if (val.trim().length < 5 || val.isEmpty) {
return "user name is very Short";
} else if (val.trim().length < 10 || val.isEmpty) {
return "user name is very long";
} else {
return null;
}
},
onSaved: (val) => username = val,
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.grey),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
border: OutlineInputBorder(),
labelText: "Username",
labelStyle: TextStyle(fontSize: 16.0),
hintText: "must be atleast 5 charecters",
hintStyle: TextStyle(color: Colors.grey),
),
),
),
),
),
GestureDetector(
onTap: submitUsername(),
child: Container(
height: 55.0,
width: 360.0,
decoration: BoxDecoration(
color: Colors.lightGreen,
borderRadius: BorderRadius.circular(8.0),
),
child: Center(
child: Text(
"Proceed",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
fontWeight: FontWeight.bold,
),
),
),
),
),
],
),
)
],
),
);
}
}
The issue was with your onTap function.
submitUsername inside onPressed is a function reference, which means it is not executed immediately. It is executed after the user clicks on the Button
While,
submitUsername() is a function call and it is executed immediately.
You should use submitUsername and not submitUsername().
GestureDetector(
onTap: submitUsername, //new line
child: Container(
height: 55.0,
width: 360.0,
decoration: BoxDecoration(
color: Colors.lightGreen,
borderRadius: BorderRadius.circular(8.0),
),
child: Center(
child: Text(
"Proceed",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
fontWeight: FontWeight.bold,
),
),
),
),
),
OR
Call the submitUsername function inside an anonymous function that will act as a callback.
GestureDetector(
onTap: (){
submitUsername();
},
child: Container(
height: 55.0,
width: 360.0,
decoration: BoxDecoration(
color: Colors.lightGreen,
borderRadius: BorderRadius.circular(8.0),
),
child: Center(
child: Text(
"Proceed",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
fontWeight: FontWeight.bold,
),
),
),
),
),

How can I eliminate this error : Incorrect use of ParentDataWidget

I didn't make use of Expanded widget but I don't know why I keep getting for this error.
Uncaught exception by widget library, Incorrect use of ParentDataWidget in four places I can't get where exactly the error is coming from. though it doesn't stop me from using the application but I feel it should be fixed. please can anyone help me?
This is my code below:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:erg_app/Anchors.dart';
import 'package:erg_app/api/api.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LogIn extends StatefulWidget {
#override
_LogInState createState() => _LogInState();
}
class _LogInState extends State<LogIn> {
bool _isLoading = false;
TextEditingController mailController = TextEditingController();
TextEditingController passwordController = TextEditingController();
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
ScaffoldState scaffoldState;
_showMsg() {
final snackBar = SnackBar(
content: Text(
'Invalid Username or Password',
style: (TextStyle(fontSize: 18)),
),
backgroundColor: Colors.amber[900],
);
_scaffoldKey.currentState.showSnackBar(snackBar);
}
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
},
child: Scaffold(
key: _scaffoldKey,
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
stops: [0.0, 0.4, 0.9],
colors: [
Color(0XFF4CAF50),
Color(0xFF388E3C),
Color(0xFF075009),
],
),
),
child: ListView(
children: <Widget>[
/////////// background///////////
SizedBox(height: 30),
new Container(
width: 100.00,
height: 100.00,
decoration: new BoxDecoration(
image: new DecorationImage(
image: AssetImage('assets/images/icon.png'),
fit: BoxFit.contain,
),
)),
Column(
children: <Widget>[
Positioned(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Positioned(
left: 30,
top: 100,
child: Container(
margin: EdgeInsets.only(top: 50),
child: Center(
child: Text(
"Welcome",
style: TextStyle(
color: Colors.white,
fontSize: 23,
fontWeight: FontWeight.bold),
),
),
),
),
SizedBox(height: 30),
Card(
elevation: 4.0,
color: Colors.white,
margin: EdgeInsets.only(left: 20, right: 20),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)),
child: Padding(
padding: const EdgeInsets.all(10.0),
// child: form(key: _formKey),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
///////////// Email//////////////
TextField(
style: TextStyle(color: Color(0xFF000000)),
controller: mailController,
cursorColor: Color(0xFF9b9b9b),
keyboardType: TextInputType.text,
decoration: InputDecoration(
prefixIcon: Icon(
Icons.account_circle,
color: Colors.grey,
),
hintText: "Username",
hintStyle: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 15,
fontWeight: FontWeight.normal),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.green)),
),
),
/////////////// password////////////////////
TextField(
style: TextStyle(color: Color(0xFF000000)),
cursorColor: Color(0xFF9b9b9b),
controller: passwordController,
keyboardType: TextInputType.number,
obscureText: true,
decoration: InputDecoration(
prefixIcon: Icon(
Icons.vpn_key,
color: Colors.grey,
),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.green)),
hintText: "Password",
hintStyle: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 15,
fontWeight: FontWeight.normal),
),
),
///////////// LogIn Botton///////////////////
Padding(
padding: const EdgeInsets.all(10.0),
child: FlatButton(
child: Padding(
padding: EdgeInsets.only(
top: 8,
bottom: 8,
left: 10,
right: 10),
child: Text(
_isLoading ? 'Loging...' : 'Login',
textDirection: TextDirection.ltr,
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
color: Colors.green,
disabledColor: Colors.grey,
shape: new RoundedRectangleBorder(
borderRadius:
new BorderRadius.circular(20.0)),
onPressed: _isLoading ? null : _login,
),
),
],
),
),
),
//////////// new account///////////////
Padding(
padding: const EdgeInsets.only(top: 20),
child: InkWell(
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => LogIn()));
},
child: Text(
'Forgot Your Password?',
textDirection: TextDirection.ltr,
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
),
],
),
),
),
],
)
],
),
),
));
// Gesture ends here
}
}
this is the picture of the error message:
You have a Positioned widget inside Column widgets in different parts of your code.
A Positioned widget must be a descendant of a Stack, and the path from
the Positioned widget to its enclosing Stack must contain only
StatelessWidgets or StatefulWidgets
I pasted the above from Flutter docs and it says that a Positioned must be descendant of a Stack i.e you cannot have a position inside other Widgets aside from a Stack widget.
You should remove the Positioned widgets from your code. or wrap them with a Stack widget
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:erg_app/Anchors.dart';
import 'package:erg_app/api/api.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LogIn extends StatefulWidget {
#override
_LogInState createState() => _LogInState();
}
class _LogInState extends State<LogIn> {
bool _isLoading = false;
TextEditingController mailController = TextEditingController();
TextEditingController passwordController = TextEditingController();
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
ScaffoldState scaffoldState;
_showMsg() {
final snackBar = SnackBar(
content: Text(
'Invalid Username or Password',
style: (TextStyle(fontSize: 18)),
),
backgroundColor: Colors.amber[900],
);
_scaffoldKey.currentState.showSnackBar(snackBar);
}
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
},
child: Scaffold(
key: _scaffoldKey,
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
stops: [0.0, 0.4, 0.9],
colors: [
Color(0XFF4CAF50),
Color(0xFF388E3C),
Color(0xFF075009),
],
),
),
child: ListView(
children: <Widget>[
/////////// background///////////
SizedBox(height: 30),
new Container(
width: 100.00,
height: 100.00,
decoration: new BoxDecoration(
image: new DecorationImage(
image: AssetImage('assets/images/icon.png'),
fit: BoxFit.contain,
),
)),
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 50),
child: Center(
child: Text(
"Welcome",
style: TextStyle(
color: Colors.white,
fontSize: 23,
fontWeight: FontWeight.bold),
),
),
),
SizedBox(height: 30),
Card(
elevation: 4.0,
color: Colors.white,
margin: EdgeInsets.only(left: 20, right: 20),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)),
child: Padding(
padding: const EdgeInsets.all(10.0),
// child: form(key: _formKey),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
///////////// Email//////////////
TextField(
style: TextStyle(color: Color(0xFF000000)),
controller: mailController,
cursorColor: Color(0xFF9b9b9b),
keyboardType: TextInputType.text,
decoration: InputDecoration(
prefixIcon: Icon(
Icons.account_circle,
color: Colors.grey,
),
hintText: "Username",
hintStyle: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 15,
fontWeight: FontWeight.normal),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.green)),
),
),
/////////////// password////////////////////
TextField(
style: TextStyle(color: Color(0xFF000000)),
cursorColor: Color(0xFF9b9b9b),
controller: passwordController,
keyboardType: TextInputType.number,
obscureText: true,
decoration: InputDecoration(
prefixIcon: Icon(
Icons.vpn_key,
color: Colors.grey,
),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.green)),
hintText: "Password",
hintStyle: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 15,
fontWeight: FontWeight.normal),
),
),
///////////// LogIn Botton///////////////////
Padding(
padding: const EdgeInsets.all(10.0),
child: FlatButton(
child: Padding(
padding: EdgeInsets.only(
top: 8,
bottom: 8,
left: 10,
right: 10),
child: Text(
_isLoading ? 'Loging...' : 'Login',
textDirection: TextDirection.ltr,
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
color: Colors.green,
disabledColor: Colors.grey,
shape: new RoundedRectangleBorder(
borderRadius:
new BorderRadius.circular(20.0)),
onPressed: _isLoading ? null : _login,
),
),
],
),
),
),
//////////// new account///////////////
Padding(
padding: const EdgeInsets.only(top: 20),
child: InkWell(
onTap: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => LogIn()));
},
child: Text(
'Forgot Your Password?',
textDirection: TextDirection.ltr,
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
),
],
),
),
],
)
],
),
),
));
// Gesture ends here
}
}