In current age, Most of mobile apps have Login-Signup. So Login and Signup is needed functionality for all mobile apps. So we are trying to implement Login/Signup UI with validation and animation. It’s simple looks but attractive and useful in all apps.
You can Download Source Code via Github.
Animation
You have to add lib for animation in .yaml file.
simple_animations: ^1.3.3
FadeAnimation.dart
class FadeAnimation extends StatelessWidget {
final double delay;
final Widget child;
FadeAnimation(this.delay, this.child);
@override
Widget build(BuildContext context) {
final tween = MultiTrackTween([
Track("opacity").add(Duration(milliseconds: 500), Tween(begin: 0.0, end: 1.0)),
Track("translateY").add(
Duration(milliseconds: 500), Tween(begin: -30.0, end: 0.0),
curve: Curves.easeOut)
]);
return ControlledAnimation(
delay: Duration(milliseconds: (500 * delay).round()),
duration: tween.duration,
tween: tween,
child: child,
builderWithChild: (context, child, animation) => Opacity(
opacity: animation["opacity"],
child: Transform.translate(
offset: Offset(0, animation["translateY"]),
child: child
),
),
);
}
}
Validation
Here we implement all validation in one file and we will use that methods in whole projects.
validation-util.dart
class ValidationUtil {
String validateEmail(String value) {
if (value.isEmpty) {
return StringUtils.enterEmail;
} else if (!RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~][email protected][a-zA-Z0-9]+\.[a-zA-Z]+")
.hasMatch(value)) {
return StringUtils.enterValidEmail;
}
return null;
}
bool isValidEmail(String value) {
if (value.isEmpty) {
return false;
} else if (!RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~][email protected][a-zA-Z0-9]+\.[a-zA-Z]+")
.hasMatch(value)) {
return false;
}
return true;
}
String validatePassword(String value) {
if (value.isEmpty) {
return StringUtils.enterPassword;
} else if (!RegExp("^.{6,30}").hasMatch(value)) {
return StringUtils.enterValidPassword;
}
return null;
}
String validateConfirmPassword(String confirmvalue, String password) {
if (confirmvalue.isEmpty) {
return StringUtils.enterConfirmPassword;
} else if (confirmvalue.compareTo(password) != 0) {
return StringUtils.enterMatchPassword;
}
return null;
}
String validatePhoneNumberField(String value) {
if (value.isEmpty) {
return StringUtils.enterPhoneNumber;
} else if (value.length < 9 && value.length > 20) {
return StringUtils.enterValidPhoneNumber;
}
return null;
}
bool isValidPhoneNumber(String value) {
if (value.isEmpty) {
return false;
} else if (value.length > 9 && value.length < 50) {
value = value.replaceAll(new RegExp(r'[^\w\s]+'), '');
value = value.replaceAll(' ', '');
if (isNumeric(value)) {
return true;
}
return false;
}
return false;
}
bool isNumeric(String s) {
if (s == null) {
return false;
}
return double.parse(s, (e) => null) != null;
}
String validateField(String value, String errorMessage) {
if (value.isEmpty) {
return errorMessage;
}
return null;
}
static bool validateFieldEmpty(String value) {
if (value.isEmpty) {
return false;
}
return true;
}
}
Widgets
Here we implement Widgets for Text Fields to make attractive and simple
Widget makeInput(
bool _validate, TextEditingController controller, String message,
{label, obscureText = false}) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
label,
style: TextStyle(
fontSize: 15, fontWeight: FontWeight.w400, color: Colors.black87),
),
SizedBox(
height: 5,
),
TextFormField(
obscureText: obscureText,
controller: controller,
validator: (value) => _validationUtil.validateField(value, message),
decoration: InputDecoration(
errorText: _validate ? message : null,
contentPadding: EdgeInsets.symmetric(vertical: 0, horizontal: 10),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey[400])),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey[400])),
),
),
SizedBox(
height: 10,
),
],
);
}
Now, we can see how we can use animation with Text fields in Login and Signup . And it’s looking simple and attractive. Let’s see
SingleChildScrollView(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 30),
height: MediaQuery.of(context).size.height - 100,
width: double.infinity,
child: Form(
key: _formKey,
child: Stack(children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Column(
children: <Widget>[
FadeAnimation(
1,
Text(
"Sign in",
style: TextStyle(
fontSize: 30, fontWeight: FontWeight.bold),
)),
],
),
Column(
children: <Widget>[
FadeAnimation(
1.2,
makeInput(_validateUserName, _textUserName,
'Please enter Username',
label: "Username")),
FadeAnimation(
1.3,
makeInput(_validatePassword, _textPassword,
'Please enter Password',
label: "Password", obscureText: true)),
],
),
FadeAnimation(
1.4,
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border(
bottom: BorderSide(color: Colors.black),
top: BorderSide(color: Colors.black),
left: BorderSide(color: Colors.black),
right: BorderSide(color: Colors.black),
)),
child: MaterialButton(
minWidth: double.infinity,
height: 50,
onPressed: () {
if (_formKey.currentState.validate()) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => HomePage()));
}
//checkAndSave();
},
color: ColorUtils.appColor,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
child: Text(
"Sign in",
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 18,
color: Colors.white),
),
),
)),
FadeAnimation(
1.6,
InkWell(
onTap: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => SignupPage()));
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Don't have an account?"),
Text(
"Sign up",
style: TextStyle(
fontWeight: FontWeight.w600, fontSize: 18),
),
],
))),
],
),
]),
),
),
),
You can Download Source Code via Github.
Hey very interesting blog!
Thanks a lot for the post.Really thank you! Cool.