How to create a login screen in Flutter
Sure, here’s a detailed blog on how to create a login screen in Flutter:
In any mobile application, authentication is an essential aspect to ensure the security of user data. Creating a login screen is the first step towards achieving authentication in an app. In this tutorial, we’ll be discussing how to create a login screen in Flutter.
Step 1: Create a new Flutter project
The first step in creating any Flutter app is to create a new project. You can use the following command in your terminal to create a new Flutter project:
flutter create login_screen
Step 2: Add dependencies
To create a login screen, we’ll be using the flutter_bloc
package. This package provides an easy and efficient way to implement the Bloc design pattern in your app. You can add the following dependencies to your pubspec.yaml
file:
dependencies:
flutter:
sdk: flutter
flutter_bloc: ^7.4.0
equatable: ^2.0.3
Step 3: Create a login screen UI
Once you’ve set up the project and added the required dependencies, it’s time to create a login screen UI. You can create a new file named login_screen.dart
and add the following code:
import 'package:flutter/material.dart';
class LoginScreen extends StatelessWidget {
const LoginScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Login Screen'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const TextField(
decoration: InputDecoration(
labelText: 'Email',
),
),
const SizedBox(height: 16),
const TextField(
obscureText: true,
decoration: InputDecoration(
labelText: 'Password',
),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {},
child: const Text('Login'),
),
],
),
),
);
}
}
In this code, we’ve created a simple login screen UI with two TextField
widgets to accept email and password inputs, and an ElevatedButton
widget to trigger the login process.
Step 4: Create a Login Bloc
To handle the login process, we’ll be using a LoginBloc
. You can create a new file named login_bloc.dart
and add the following code:
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
part 'login_event.dart';
part 'login_state.dart';
class LoginBloc extends Bloc<LoginEvent, LoginState> {
LoginBloc() : super(LoginInitial());
@override
Stream<LoginState> mapEventToState(LoginEvent event) async* {
if (event is LoginButtonPressed) {
yield LoginLoading();
try {
// Replace this with your own login logic
await Future.delayed(const Duration(seconds: 2));
yield LoginSuccess();
} catch (error) {
yield LoginFailure(error: error.toString());
}
}
}
}
In this code, we’ve created a LoginBloc
that extends the Bloc
class from the flutter_bloc
package. The LoginBloc
has three states:
LoginInitial
: The initial state of the bloc.LoginLoading
: The state when the login process is in progress.LoginSuccess
: The state when the login process is successful.LoginFailure
: The state when the login process fails.
The mapEventToState
method maps the incoming
events to the corresponding states. In this case, we’re listening to the LoginButtonPressed event and triggering the login process. We’ve also added a delay of 2 seconds to simulate a login process. You can replace this with your own login logic.
Step 5: Create Login Events
To trigger the login process, we’ll be using a LoginButtonPressed event. You can create a new file named login_event.dart and add the following code:
part of 'login_bloc.dart';
abstract class LoginEvent extends Equatable {
const LoginEvent();
@override
List<Object> get props => [];
}
class LoginButtonPressed extends LoginEvent {
final String email;
final String password;
const LoginButtonPressed({required this.email, required this.password});
@override
List<Object> get props => [email, password];
@override
String toString() => 'LoginButtonPressed { email: $email, password: $password }';
}
In this code, we’ve created a LoginButtonPressed
event that takes email and password as arguments. This event will be triggered when the user taps the login button.
Step 6: Create Login States
We’ve already created the LoginState
in the login_bloc.dart
file. We'll now add the implementation for each state. You can create a new file named login_state.dart
and add the following code:
part of 'login_bloc.dart';
abstract class LoginState extends Equatable {
const LoginState();
@override
List<Object> get props => [];
}
class LoginInitial extends LoginState {}
class LoginLoading extends LoginState {}
class LoginSuccess extends LoginState {}
class LoginFailure extends LoginState {
final String error;
const LoginFailure({required this.error});
@override
List<Object> get props => [error];
@override
String toString() => 'LoginFailure { error: $error }';
}
In this code, we’ve implemented each state of the LoginBloc
. The LoginInitial
state is the initial state of the bloc. The LoginLoading
state is triggered when the login process is in progress. The LoginSuccess
state is triggered when the login process is successful. The LoginFailure
state is triggered when the login process fails and takes an error message as an argument.
Step 7: Implement the Login Process
Now that we’ve created the UI, bloc, events, and states, it’s time to implement the login process. You can modify the LoginScreen
widget to listen to the events and update the UI based on the states. Here's the updated code for LoginScreen
:
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'login_bloc.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({
Key ? key
}): super(key: key);
@override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State < LoginScreen > {
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
@override
void dispose() {
_emailController.dispose();
_passwordController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final loginBloc = BlocProvider.of < LoginBloc > (context);
return Scaffold(
appBar: AppBar(
title: const Text('Login Screen'),
),
body: BlocListener < LoginBloc, LoginState > (
listener: (context, state) {
if (state is LoginFailure) {
ScaffoldMessenger.of(context)..hideCurrentSnackBar()..showSnackBar(SnackBar(
content: Text(state.error),
duration: const Duration(seconds: 3),
));
}
},
child: BlocBuilder < LoginBloc, LoginState > (
builder: (context, state) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: < Widget > [
TextFormField(
controller: _emailController,
decoration: const InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
TextFormField(
controller: _passwordController,
obscureText: true,
decoration: const InputDecoration(
labelText: 'Password',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: state is!LoginLoading ?
() {
loginBloc.add(
LoginButtonPressed(
email: _emailController.text,
password: _passwordController.text,
),
);
} :
null,
child: const Text('Login'),
),
if (state is LoginLoading)
const Padding(
padding: EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
),
],
),
);
},
),
),
);
}
}
In this code, we’ve added a BlocListener BlocListener
that listens to the LoginFailure
state and shows a SnackBar
with the error message. We’ve also added a BlocBuilder
that rebuilds the UI based on the current state. If the current state is LoginLoading
, we show a CircularProgressIndicator
to indicate that the login process is in progress. We’ve also disabled the login button when the login process is in progress.
Step 8: Test the Login Screen
Now that we’ve implemented the login screen, it’s time to test it. Run the app and enter a valid email and password. You should see a CircularProgressIndicator
indicating that the login process is in progress.
After a delay of 2 seconds, you should see the LoginSucess
state and the app should navigate to the home screen. If you enter an invalid email or password, you should see the LoginFailure
state and a SnackBar
with the error message.
if you want to create a social media or finance app then you should hire a flutter app development engineers.
Conclusion
In this blog post, we’ve learned how to create a login screen in Flutter using the BLoC pattern. We’ve created a UI for the login screen, implemented a LoginBloc
to to handle the business logic, created events and states, and implemented the login process. By following these steps, you can create a robust and scalable login screen for your Flutter app.