Splash Screen
Loading preview
Starting the Flutter app
Animated logo scale-in, name fade-in, loading indicator
import 'package:flutter/material.dart';
class SplashScreen extends StatefulWidget {
const SplashScreen({super.key});
@override
State<SplashScreen> createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _scaleAnimation;
late Animation<double> _fadeAnimation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 1500),
vsync: this,
);
_scaleAnimation = Tween<double>(begin: 0.5, end: 1.0).animate(
CurvedAnimation(
parent: _controller,
curve: const Interval(0.0, 0.6, curve: Curves.easeOut),
),
);
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: _controller,
curve: const Interval(0.4, 1.0, curve: Curves.easeIn),
),
);
_controller.forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ScaleTransition(
scale: _scaleAnimation,
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(20),
),
child: Icon(
Icons.flutter_dash,
size: 60,
color: Theme.of(context).colorScheme.onPrimary,
),
),
),
const SizedBox(height: 24),
FadeTransition(
opacity: _fadeAnimation,
child: Text(
'App Name',
style: Theme.of(context).textTheme.headlineMedium,
),
),
const SizedBox(height: 32),
const SizedBox(
width: 24,
height: 24,
child: CircularProgressIndicator(strokeWidth: 2),
),
],
),
),
);
}
}
Add it to your project
Copies the Dart source into your app, so you own it. Flutter SDK only, no extra packages.
First time? Run dart pub global activate fluttertemplates_dev, or read the CLI guide.
How it works
One AnimationController drives two overlapping Intervals: _scaleAnimation over the first 60% and _fadeAnimation over the last 60%, so the logo pops before the title fades in. There’s no completion handling, so the screen stays forever with its spinner running. The logo background reads primaryColor while the icon uses onPrimary, which aren’t always a matched pair.
Adapting it
- Add a status listener to
_controller, and navigate when both animation and app init finish. - Replace
Icons.flutter_dashandApp Namewith your branding. - Use
colorScheme.primaryfor the logo box, and configure native splash separately.