Hi to everyone! We think you all are good and do Somthings unique in your life. So in this article, we learn how to create a beautiful Login Page UI with some front-end validation like not empty, email not well manner and the password must be strong.
Why we use
It’s a good practice to authenticate users before giving access to websites, mobile apps, and computer applications to prevent unauthorized access to personal information. In this article, I am going to explain how to build a login page user interface. we have used the TextField widget and packages like email_validator for user input as email and password.
Step 1: Create or open the Flutter project
In my case, I am using Android Studio IDE for the code you choose which is better for you. You can use editors like Visual Studio Code, Android Studio, or IntelliJ IDEA respectively.
flutter create your_project_name
cd your_project_name
Step 2: Update pubspec.yaml
for package
The pubspec.yaml
file is where you declare the dependencies for your Flutter project. Open the pubspec.yaml
file and add the email_validator dependency to it.
dependencies:
email_validator: ^2.1.17
Step 3: Save the file and run flutter pub get
After adding the dependency in the pubspec.yaml
file, save the changes, and in your terminal or command prompt, run:
flutter pub get
This command will fetch and download the email_validator
package along with its dependencies.
Step 4: Import the email_validator package in your Flutter app
In the Dart files where you want to use the email_validator import it at the top:
import 'package:email_validator/email_validator.dart';
If you don’t want the email_validator package then you use simple functionality to check email format see my last blog Email Validation In the Flutter.
Step 5: Use the TextFormField
The main purpose of <strong><a href="https://api.flutter.dev/flutter/material/TextFormField-class.html" target="_blank" rel="noreferrer noopener">TextFormField</a></strong>
is to handle text input and validation in a user-friendly way. It extends the functionality of the basic TextField
widget by providing built-in validation and error-handling features. In this example simple TexFormFeild with border.
TextField(
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 3, color: Colors.greenAccent), //<-- SEE HERE
),
),
)
Step 6: Form Key
The <strong><a href="https://docs.flutter.dev/cookbook/forms/validation" target="_blank" rel="noreferrer noopener">Form</a></strong>
widget keeps track of the form’s state and holds multiple form fields, while the <strong>TextFormField</strong>
represents an individual form field. Each TextFormField
requires a unique identifier, and that’s where the Form
key comes into play.
Here’s an explanation of how to use the Form
key with TextFormField
:
import 'package:flutter/material.dart';
class MyForm extends StatefulWidget {
@override
_MyFormState createState() => _MyFormState();
}
class _MyFormState extends State<MyForm> {
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Form(
key: _formKey, // Set the form key here
child: Column(
children: [
// Add TextFormField widgets here
],
),
);
}
}
If you go more dipper in validate Forms & AutoComplete & Typeahead then check my blog Create and Validate Forms With AutoComplete & Typeahead.
Step 7: Here is the full code of the Login Page UI with validation
Open your main.dart file and paste this code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'HomeSceen.dart';
import 'package:email_validator/email_validator.dart';
void main() {
runApp(App());
}
class App extends StatefulWidget {
App({super.key});
@override
State<App> createState() => _AppState();
}
class _AppState extends State<App> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "App Rating",
home: LoginScreen(),
);
}
}
class LoginScreen extends StatefulWidget {
LoginScreen({Key? key}) : super(key: key);
@override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
bool _passwordVisible = true;
bool deleteVisible = false;
bool _validate = false;
final emailControler = TextEditingController();
final passwordControler = TextEditingController();
final _formKey = GlobalKey<FormState>();
String _email = '';
String _password = '';
@override
void initState() {
super.initState();
}
String? validatePassword(String? value) {
// Password must contain at least one uppercase letter.
if (!value!.contains(RegExp(r'[A-Z]'))) {
return 'Password must contain at least one uppercase letter';
}
// Password must contain at least one digit.
if (!value.contains(RegExp(r'\d'))) {
return 'Password must contain at least one digit';
}
// Password must contain at least one special character (non-alphanumeric).
if (!value.contains(RegExp(r'[!@#$%^&*(),.?":{}|<>]'))) {
return 'Password must contain at least one special character';
}
// Password length must be greater than 8 characters.
if (value.length < 8) {
return 'Password must be at least 8 characters long';
}
return null; // Password is valid.
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.white,
body: SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 20,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset('Assets/images/login.jpg'),
SizedBox(height: 30),
Text(
"Login now",
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.w700,
),
),
SizedBox(height: 20),
Text(
"please enter the detailes below to continue",
style: TextStyle(
fontSize: 16,
),
),
Spacer(),
Form(
key: _formKey,
child: Column(
children: <Widget>[
//email
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20,
),
child: Container(
decoration: BoxDecoration(
color: const Color(0xFFF7F8F9),
border: Border.all(
color: const Color(0xFFE8ECF4),
),
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: const EdgeInsets.only(
left: 10,
right: 10,
),
child: TextFormField(
autovalidateMode:
AutovalidateMode.onUserInteraction,
keyboardType: TextInputType.emailAddress,
controller: emailControler,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Enter your email',
hintStyle: TextStyle(
color: Color(0xFF8391A1),
),
errorText:
_validate ? 'Value Can\'t Be Empty' : null,
suffixIcon: IconButton(
icon: Icon(
deleteVisible ? Icons.close : null,
color: Colors.black,
),
onPressed: () {
emailControler.clear();
},
),
),
onChanged: (value) {
setState(() {
value.length > 0
? deleteVisible = true
: deleteVisible = false;
});
},
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your email';
}
if (!EmailValidator.validate(value)) {
return 'Please enter a valid email';
}
return null;
},
onSaved: (value) {
_email = value!;
},
),
),
),
),
SizedBox(height: 15),
//password
Padding(
padding: EdgeInsets.symmetric(
horizontal: 20,
),
child: Container(
decoration: BoxDecoration(
color: Color(0xFFF7F8F9),
border: Border.all(
color: Color(0xFFE8ECF4),
),
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: EdgeInsets.only(
left: 10,
right: 10,
),
child: TextFormField(
autocorrect: false,
controller: passwordControler,
autovalidateMode:
AutovalidateMode.onUserInteraction,
keyboardType: TextInputType.text,
obscureText: _passwordVisible,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Enter your password',
hintStyle: TextStyle(
color: Color(0xFF8391A1),
),
suffixIcon: IconButton(
icon: Icon(
// Based on passwordVisible state choose the icon
_passwordVisible
? Icons.visibility
: Icons.visibility_off,
color: Colors.black,
),
onPressed: () {
// Update the state i.e. toogle the state of passwordVisible variable
setState(() {
_passwordVisible = !_passwordVisible;
});
},
),
),
validator: validatePassword,
onChanged: (value) {
setState(() {
if (validatePassword(value) == null) {
print("yes");
} else {
print("error");
}
});
},
),
),
),
),
],
),
),
//forgot password
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 10,
),
child: Align(
alignment: Alignment.centerRight,
child: GestureDetector(
onTap: () {},
child: const Text(
"Forgot Password?",
style: TextStyle(
color: Color(0xFF6A707C),
),
),
),
),
),
Spacer(),
//login button
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 5,
),
child: Row(
children: [
Expanded(
child: MaterialButton(
color: const Color(0xFFe91e63),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
onPressed: () {
final isValidate = _formKey.currentState!.validate();
if (isValidate) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const HomeScreen()));
}
},
child: const Padding(
padding: EdgeInsets.all(15.0),
child: Text(
"Login",
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
),
),
),
],
),
),
Spacer(),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 10,
),
child: Row(
children: const [
Expanded(
child: Divider(
color: Color(0xFFE8ECF4),
thickness: 1,
),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 10,
),
child: Text("Or Login With"),
),
Expanded(
child: Divider(
color: Color(0xFFE8ECF4),
thickness: 1,
),
),
],
),
),
Spacer(),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 20,
),
child: Row(
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Color(0xFFE8ECF4),
),
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: EdgeInsets.all(12.0),
child: Image.asset(
"Assets/images/fb.png",
height: 32,
),
),
),
),
SizedBox(width: 10),
Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Color(0xFFE8ECF4),
),
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: EdgeInsets.all(12.0),
child: Image.asset(
"Assets/images/google.png",
height: 32,
),
),
),
),
SizedBox(width: 10),
Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Color(0xFFE8ECF4),
),
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: EdgeInsets.all(12.0),
child: Image.asset(
"Assets/images/apple.png",
height: 32,
),
),
),
),
],
),
),
Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Don’t have an account? ",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
GestureDetector(
onTap: () {},
child: Text(
"Register",
style: TextStyle(
color: Color(0xFFe91e63),
fontSize: 16,
fontWeight: FontWeight.w700,
),
),
),
],
),
],
),
),
),
);
}
}
Output
Conclusion:
Designing a stunning login page UI in Flutter involves a combination of creativity, understanding user needs, and technical implementation. Through this blog, we’ve learned how to leverage Flutter’s powerful features to craft an attractive and user-friendly login interface. By applying these principles and iterating based on user feedback, you can create an outstanding login experience that leaves a lasting positive impression on your users.
❤️❤️ Thanks for reading this article ❤️❤️
If I got something wrong? Let me know in the comments. I would love to improve 🥰🥰🥰.
Clap 👏👏👏 If this article helps you.
if you like our work so please follow us on this Dosomthings