i try to save value in EMAIL variable with onChanged by used setState but the setState function not defined. i can't call it . MyTextField is statefulWidget. what is problem i don't know .is problem related with Widget class (_buildAllTextFormField)? or what i'm beginner can anyone help me please?
import 'package:ecommernce_application/screens/signup.dart';
import 'package:flutter/material.dart';
import '../widgets/move_to_sign_or_login_screen.dart';
import '../widgets/sign_login_button.dart';
import '../widgets/text_field.dart';
class Login extends StatefulWidget {
const Login({Key? key}) : super(key: key);
@override
State<Login> createState() => _LoginState();
}
final _formKey = GlobalKey<FormState>();
bool obscureText = true;
// for validate Email
String pEmail = r'^(([^<>()[\]\\.,;:\s@\"] (\.[^<>()[\]\\.,;:\s@\"] )*)|(\". \"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9] \.) [a-zA-Z]{2,}))$';
RegExp regExp = RegExp(pEmail);
void validate(){
final FormState? form = _formKey.currentState;
if(form!.validate())
{ debugPrint('Yes'); }
else { debugPrint('No'); }
}
String EMAIL='';
Widget _buildAllTextFormField(BuildContext context){
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.only(top: 100),
width: double.infinity,
height: 240,
alignment: Alignment.center,
child: const Text('Login',style: TextStyle(fontSize: 40,),),
),
const SizedBox(height: 10,),
Form(
key: _formKey,
autovalidateMode: AutovalidateMode.always,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 10,),
MyTextField(
onChanged:(v){
///////////////cant call setState The function 'setState' isn't defined
//setState((){});
},
controller: email,
validator: (String? value) {
if(value == null || value.trim().isEmpty) {
return 'Please enter your email address';
} // Check if the entered email has the right format
if (!regExp.hasMatch(value)) {
return 'Please enter a valid email address';
} // Return null if the entered email is valid
return null;
},
name: 'Email',),
const SizedBox(height: 10,),
MyTextField(
onChanged: (value){
},
controller: password,
name: 'Password',
validator: (value){
if (value == null || value.trim().isEmpty) {
return 'This field is required';
}
if (value.trim().length < 8) {
return 'Password must be at least 8 characters in length';
} // Return null if the entered password is valid
return null;
}),
const SizedBox(height: 10,),
_buildBottomPart(context),
],
),
),
],
);
}
Widget _buildBottomPart(BuildContext context){
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SignLoginButton(
name: 'Login',
onPressed:() { validate(); } ,
color: Colors.grey,
),
const SizedBox( height: 10, ),
Padding(
padding: const EdgeInsets.only( left:8.0 ),
child:MoveToScreen(
text1:'I Have Noy Account',
text2:'SignUp',
onTap: () {
Navigator.of(context).pushReplacement ( MaterialPageRoute(builder: (context) => const SignUP() ) );
},
),
),
],
);
}
final TextEditingController email = TextEditingController();
final TextEditingController password = TextEditingController();
class _LoginState extends State<Login> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: SingleChildScrollView(
child:TextField(
onChanged: (v){
setState(() {
});
},
),
// _buildAllTextFormField(context),
),
),
);
}
MyTextField
import 'package:flutter/material.dart';
class MyTextField extends StatefulWidget {
final TextEditingController controller;
final String name;
final ValueChanged<String> onChanged;
final FormFieldValidator<String> validator;
const MyTextField({Key? key ,required this.onChanged,required this.controller, required this.name, required this.validator,}) : super(key: key);
@override
State<MyTextField> createState() => _MyTextFieldState();
}
class _MyTextFieldState extends State<MyTextField> {
@override
Widget build(BuildContext context) {
return SizedBox(
width: 400,
height: 50,
child: TextFormField(
controller: widget.controller,
validator: widget.validator,
onChanged: widget.onChanged,
decoration: InputDecoration(
labelText: widget.name,
border: const OutlineInputBorder(),
),
),
);
}
}
PasswordTextField
import 'package:flutter/material.dart';
class PasswordTextField extends StatefulWidget {
final TextEditingController controller;
final String name;
final FormFieldValidator<String> validator;
//final ValueChanged<String> onChange;
const PasswordTextField({Key? key, required this.controller, required this.name, required this.validator}) : super(key: key);
@override
State<PasswordTextField> createState() => _PasswordTextFieldState();
}
class _PasswordTextFieldState extends State<PasswordTextField> {
bool _obscureText = true ;
@override
Widget build(BuildContext context) {
return SizedBox(
width: 400,
height: 50,
child: TextFormField(
obscureText: _obscureText,
validator: widget.validator,
//onChanged: widget.onChange,
controller: widget.controller,
decoration: InputDecoration(
suffixIcon: GestureDetector(
onTap: (){
setState(() {
_obscureText =!_obscureText;
});
FocusScope.of(context).unfocus();
},
child: Icon( _obscureText == true ? Icons.visibility : Icons.visibility_off,color: Colors.black,),),
labelText: widget.name,
border: const OutlineInputBorder(),
),
),
);
}
}
CodePudding user response:
You can do it in this way:
Widget _buildAllTextFormField(BuildContext context, Function() changeCallback){...}
then replace:
_buildAllTextFormField(context)
with
_buildAllTextFormField(context, () => setState((){}))
and then replace:
onChanged:(v){
///////////////cant call setState The function 'setState' isn't defined
//setState((){});
},
with:
onChanged:(v){
changeCallback.call();
},