Learn how to build a stunning animated login and register screen in Flutter with smooth transitions and modern UI design. Updated for 2025 with best practices and clean code.
anand

Learn how to build a stunning animated login and register screen in Flutter with smooth transitions, glassmorphism effects, and modern UI design. Complete code included!

Introduction
Creating an engaging Flutter login screen is crucial for making a great first impression on your app users. In this comprehensive guide, we'll build a beautiful animated login and register screen that combines modern UI design with smooth animations and excellent user experience.
This Flutter authentication UI features glassmorphism effects, smooth transitions, and a professional gradient background that will make your app stand out in 2025. Whether you're building a social media app, e-commerce platform, or any mobile application, this login screen template will provide the perfect starting point.
Our animated Flutter login screen includes these powerful features:
LinearGradientsetStateHere's the complete Flutter login screen code with all animations and features:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Animated Login',
theme: ThemeData(
primarySwatch: Colors.blue,
fontFamily: 'Roboto',
),
home: AuthScreen(),
debugShowCheckedModeBanner: false,
);
}
}
class AuthScreen extends StatefulWidget {
@override
_AuthScreenState createState() => _AuthScreenState();
}
class _AuthScreenState extends State
with TickerProviderStateMixin {
late AnimationController _controller;
late AnimationController _fadeController;
late Animation _animation;
late Animation _fadeAnimation;
late Animation _slideAnimation;
bool isLogin = true;
bool _obscurePassword = true;
bool _obscureConfirmPassword = true;
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
final _confirmPasswordController = TextEditingController();
final _nameController = TextEditingController();
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(milliseconds: 800),
vsync: this,
);
_fadeController = AnimationController(
duration: Duration(milliseconds: 400),
vsync: this,
);
_animation = CurvedAnimation(
parent: _controller,
curve: Curves.easeInOutCubic,
);
_fadeAnimation = CurvedAnimation(
parent: _fadeController,
curve: Curves.easeInOut,
);
_slideAnimation = Tween(
begin: Offset(0, 0.3),
end: Offset.zero,
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeOutBack,
));
_controller.forward();
_fadeController.forward();
}
@override
void dispose() {
_controller.dispose();
_fadeController.dispose();
_emailController.dispose();
_passwordController.dispose();
_confirmPasswordController.dispose();
_nameController.dispose();
super.dispose();
}
void _toggleAuthMode() {
setState(() {
isLogin = !isLogin;
});
_fadeController.reset();
_fadeController.forward();
}
void _handleAuth() {
// Handle authentication logic here
String message = isLogin ? 'Login successful!' : 'Registration successful!';
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: Colors.green,
behavior: SnackBarBehavior.floating,
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF667eea),
Color(0xFF764ba2),
],
),
),
child: SafeArea(
child: Center(
child: SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 32.0),
child: SlideTransition(
position: _slideAnimation,
child: FadeTransition(
opacity: _animation,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Logo/Title Section
ScaleTransition(
scale: _animation,
child: Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: Colors.white.withOpacity(0.2),
width: 1,
),
),
child: Icon(
Icons.lock_outline,
size: 60,
color: Colors.white,
),
),
),
SizedBox(height: 40),
// Welcome Text
AnimatedBuilder(
animation: _fadeAnimation,
builder: (context, child) {
return Opacity(
opacity: _fadeAnimation.value,
child: Text(
isLogin ? 'Welcome Back!' : 'Create Account',
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
color: Colors.white,
shadows: [
Shadow(
blurRadius: 10.0,
color: Colors.black26,
offset: Offset(2.0, 2.0),
),
],
),
),
);
},
),
SizedBox(height: 8),
AnimatedBuilder(
animation: _fadeAnimation,
builder: (context, child) {
return Opacity(
opacity: _fadeAnimation.value,
child: Text(
isLogin
? 'Sign in to your account'
: 'Sign up to get started',
style: TextStyle(
fontSize: 16,
color: Colors.white.withOpacity(0.8),
),
),
);
},
),
SizedBox(height: 50),
// Form Section
Container(
padding: EdgeInsets.all(32),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 20,
offset: Offset(0, 10),
),
],
),
child: AnimatedBuilder(
animation: _fadeAnimation,
builder: (context, child) {
return Column(
children: [
// Name Field (only for register)
if (!isLogin)
AnimatedContainer(
duration: Duration(milliseconds: 300),
height: isLogin ? 0 : 80,
child: AnimatedOpacity(
opacity: isLogin ? 0 : _fadeAnimation.value,
duration: Duration(milliseconds: 300),
child: _buildTextField(
controller: _nameController,
label: 'Full Name',
icon: Icons.person_outline,
keyboardType: TextInputType.name,
),
),
),
// Email Field
FadeTransition(
opacity: _fadeAnimation,
child: _buildTextField(
controller: _emailController,
label: 'Email',
icon: Icons.email_outlined,
keyboardType: TextInputType.emailAddress,
),
),
SizedBox(height: 20),
// Password Field
FadeTransition(
opacity: _fadeAnimation,
child: _buildPasswordField(
controller: _passwordController,
label: 'Password',
obscureText: _obscurePassword,
onToggleVisibility: () {
setState(() {
_obscurePassword = !_obscurePassword;
});
},
),
),
// Confirm Password Field (only for register)
if (!isLogin) ...[
SizedBox(height: 20),
AnimatedContainer(
duration: Duration(milliseconds: 300),
height: isLogin ? 0 : 60,
child: AnimatedOpacity(
opacity: isLogin ? 0 : _fadeAnimation.value,
duration: Duration(milliseconds: 300),
child: _buildPasswordField(
controller: _confirmPasswordController,
label: 'Confirm Password',
obscureText: _obscureConfirmPassword,
onToggleVisibility: () {
setState(() {
_obscureConfirmPassword = !_obscureConfirmPassword;
});
},
),
),
),
],
// Forgot Password (only for login)
if (isLogin) ...[
SizedBox(height: 10),
Align(
alignment: Alignment.centerRight,
child: FadeTransition(
opacity: _fadeAnimation,
child: TextButton(
onPressed: () {
// Handle forgot password
},
child: Text(
'Forgot Password?',
style: TextStyle(
color: Color(0xFF667eea),
fontWeight: FontWeight.w500,
),
),
),
),
),
],
SizedBox(height: 30),
// Auth Button
FadeTransition(
opacity: _fadeAnimation,
child: Container(
width: double.infinity,
height: 55,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF667eea), Color(0xFF764ba2)],
),
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Color(0xFF667eea).withOpacity(0.3),
blurRadius: 10,
offset: Offset(0, 5),
),
],
),
child: ElevatedButton(
onPressed: _handleAuth,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.transparent,
shadowColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: Text(
isLogin ? 'Sign In' : 'Sign Up',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
),
SizedBox(height: 20),
// Divider
FadeTransition(
opacity: _fadeAnimation,
child: Row(
children: [
Expanded(child: Divider()),
Padding(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Text(
'or',
style: TextStyle(
color: Colors.grey[600],
fontWeight: FontWeight.w500,
),
),
),
Expanded(child: Divider()),
],
),
),
SizedBox(height: 20),
// Social Login Buttons
FadeTransition(
opacity: _fadeAnimation,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildSocialButton(
icon: Icons.g_mobiledata,
label: 'Google',
color: Colors.red,
),
_buildSocialButton(
icon: Icons.facebook,
label: 'Facebook',
color: Colors.blue,
),
],
),
),
],
);
},
),
),
SizedBox(height: 30),
// Switch Auth Mode
FadeTransition(
opacity: _fadeAnimation,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
isLogin
? "Don't have an account? "
: "Already have an account? ",
style: TextStyle(
color: Colors.white.withOpacity(0.8),
),
),
GestureDetector(
onTap: _toggleAuthMode,
child: Text(
isLogin ? 'Sign Up' : 'Sign In',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
decoration: TextDecoration.underline,
),
),
),
],
),
),
],
),
),
),
),
),
),
),
);
}
Widget _buildTextField({
required TextEditingController controller,
required String label,
required IconData icon,
TextInputType keyboardType = TextInputType.text,
}) {
return Container(
decoration: BoxDecoration(
color: Colors.grey[50],
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.grey[200]!),
),
child: TextField(
controller: controller,
keyboardType: keyboardType,
decoration: InputDecoration(
labelText: label,
prefixIcon: Icon(icon, color: Color(0xFF667eea)),
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 16),
labelStyle: TextStyle(color: Colors.grey[600]),
),
),
);
}
Widget _buildPasswordField({
required TextEditingController controller,
required String label,
required bool obscureText,
required VoidCallback onToggleVisibility,
}) {
return Container(
decoration: BoxDecoration(
color: Colors.grey[50],
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.grey[200]!),
),
child: TextField(
controller: controller,
obscureText: obscureText,
decoration: InputDecoration(
labelText: label,
prefixIcon: Icon(Icons.lock_outline, color: Color(0xFF667eea)),
suffixIcon: IconButton(
icon: Icon(
obscureText ? Icons.visibility_off : Icons.visibility,
color: Colors.grey[600],
),
onPressed: onToggleVisibility,
),
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 16),
labelStyle: TextStyle(color: Colors.grey[600]),
),
),
);
}
Widget _buildSocialButton({
required IconData icon,
required String label,
required Color color,
}) {
return Expanded(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 8),
height: 50,
decoration: BoxDecoration(
border: Border.all(color: Colors.grey[300]!),
borderRadius: BorderRadius.circular(12),
),
child: ElevatedButton(
onPressed: () {
// Handle social login
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, color: color, size: 24),
SizedBox(width: 8),
Text(
label,
style: TextStyle(
color: Colors.grey[700],
fontWeight: FontWeight.w500,
),
),
],
),
),
),
);
}
}
Our Flutter login animation uses multiple controllers for different effects:
_controller = AnimationController(
duration: Duration(milliseconds: 800),
vsync: this,
);
// Fade controller for mode transitions
_fadeController = AnimationController(
duration: Duration(milliseconds: 400),
vsync: this,
);_fadeAnimation = CurvedAnimation(
parent: _fadeController,
curve: Curves.easeInOut,
);_slideAnimation = Tween(
begin: Offset(0, 0.3),
end: Offset.zero,
).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeOutBack,
));
ScaleTransition(
scale: _animation,
child: Container(/* Logo */),
)
vsync Parameter: Always provide vsync for smooth animationsOur Flutter UI design incorporates current trends:
Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: Colors.white.withOpacity(0.2),
width: 1,
),
),
)
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF667eea),
Color(0xFF764ba2),
],
),
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 20,
offset: Offset(0, 10),
),
],
@override
void dispose() {
_controller.dispose();
_fadeController.dispose();
_emailController.dispose();
_passwordController.dispose();
_confirmPasswordController.dispose();
_nameController.dispose();
super.dispose();
}import 'package:firebase_auth/firebase_auth.dart';
void _handleAuth() async {
try {
if (isLogin) {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
);
} else {
await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
);
}
} catch (e) {
// Handle errors
}
}Creating a beautiful animated login screen in Flutter requires attention to detail, performance optimization, and modern design principles. This comprehensive guide provides you with a production-ready solution that combines:

Passionate about creating amazing web experiences and sharing knowledge with the developer community.
Discover more insightful articles and tutorials to expand your knowledge

Learn how to play audio in Flutter using the audioplayers package. This step-by-step guide covers playing audio from assets and network URLs, controlling playback, looping, volume management, and best practices for building real-world Flutter apps.

Improving Flutter performance in 2025 is easier than you think. From using const widgets and optimizing images to preventing unnecessary rebuilds and leveraging Flutter DevTools, this guide covers the top techniques to make your Flutter app faster, smoother, and more efficient on all devices. Learn the best practices every developer should follow to avoid lag, reduce jank, and deliver a high-performance user experience.

Flutter’s WebView widget allows developers to embed web content directly inside their mobile apps — perfect for displaying websites, dashboards, documentation, and payment gateways. With the webview_flutter package, you can load URLs, run JavaScript, manage navigation, and even communicate between your webpage and Flutter. In this guide, we walk through setup, permissions, loading pages, handling progress, and best practices to help you integrate WebView smoothly into any Flutter project.