I've been learning flutter for a while and got stuck with a not working ProgressIndicator. The problem is that it doesn't detect any error, and progressbar doesn't update anyway when you enter a password into TextFormField. And if you have any comments about the code itself, I'd love to read it and learn something new
import 'RegisterThree.dart';
import 'package:flutter/material.dart';
class RegisterSec extends StatefulWidget {
const RegisterSec({Key? key}) : super(key: key);
@override
_RegisterPage2 createState() => _RegisterPage2();
}
class _RegisterPage2 extends State<RegisterSec> {
final _formKey = GlobalKey<FormState>();
// regular expression to check if string
RegExp pass_valid = RegExp(r"(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*\W)");
double password_strength = 0;
bool validatePassword(String pass) {
String _password = pass.trim();
if (_password.isEmpty) {
setState(() {
password_strength = 0;
});
} else if (_password.length < 6) {
setState(() {
password_strength = 1 / 4;
});
} else if (_password.length < 8) {
setState(() {
password_strength = 2 / 4;
});
} else {
if (pass_valid.hasMatch(_password)) {
setState(() {
password_strength = 4 / 4;
});
return true;
} else {
setState(() {
password_strength = 3 / 4;
});
return false;
}
}
return false;
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Container(
width: double.infinity,
key: _formKey,
child: Column(
children: <Widget>[
SizedBox(height: 75),
SizedBox(
child: Text(
'Create a new password',
style: TextStyle(fontSize: 40),
textAlign: TextAlign.center,
)),
Padding(
padding: const EdgeInsets.all(20.0),
child: TextFormField(
onChanged: (value) {
_formKey.currentState!.validate();
},
validator: (value) {
if (value!.isEmpty) {
return "Password";
} else {
//call function to check password
bool result = validatePassword(value);
if (result) {
// create account event
return null;
} else {
return "Password should contain Capital, small letter & Number & Special";
}
}
},
decoration: InputDecoration(
border: UnderlineInputBorder(), hintText: "Password"),
obscureText: true,
),
),
Padding(
padding: EdgeInsets.all(20.0),
child: TextFormField(
obscureText: true,
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: 'Confirm password',
),
),
),
Padding(
padding: const EdgeInsets.all(20),
child: LinearProgressIndicator(
value: password_strength,
backgroundColor: Colors.grey[300],
minHeight: 5,
color: password_strength <= 1 / 4
? Colors.red
: password_strength == 2 / 4
? Colors.yellow
: password_strength == 3 / 4
? Colors.blue
: Colors.green,
),
),
SizedBox(
child: Text(
'Password should contain Capital, small letter & Number & Special',
style: TextStyle(
color: Color.fromARGB(255, 131, 131, 131),
fontSize: 13,
),
textAlign: TextAlign.left,
)),
SizedBox(
height: 30,
),
SizedBox(
child: ElevatedButton(
onPressed: password_strength != 1
? null
: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RegisterThree()));
},
child: Icon(Icons.navigate_next, color: Colors.white),
style: ElevatedButton.styleFrom(
shape: CircleBorder(),
padding: EdgeInsets.all(20),
primary: Colors.blue, // <-- Button color
onPrimary: Colors.white, // <-- Splash color
),
)),
SizedBox(
height: 280,
),
TextButton(
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => HomePage()));
},
child: Text(
'Go back',
style: TextStyle(color: Colors.blue, fontSize: 15),
),
),
],
),
),
);
}
}
CodePudding user response:
The reason why it does not work is that currentState is null. It is null because you have to wrap your TextFormField in a form. And to this form you have to pass the formKey, not the Container
Form(
key: _formKey,
child: Container(
width: double.infinity,
child: ...