Hello guys! Welcome to my new blog! Today we will be talking about animations in Flutter
In this blog, we’ll start from scratch to show you how to animate any widget in your Flutter app using the flutter_animate package. We’ll also walk through practical use cases for implementing the animation within your app.
The entire code discussed can be found in the repository given below.
Here is a little preview of what we will be building today
Given below is the outline of the article.
Dependencies
Make sure to add these dependencies before going ahead with the article.
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
flutter_animate: ^4.1.1+1
1. Animating a Widget
First, before we dive into deeper use cases, it is necessary to go through how we animate simple and basic widgets, like Text or an Image.
For this section, we will be using a Text widget.
Text(
'Animated Widget',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold
)
)
You can provide the text style as it suits you.
a. Wrapping in Animate( ) widget.
Applying animations to any widget is easy. All we have to do is to wrap it in an Animate( ) widget.
Animate(
child: const Text(
'Animated Widget',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold
)
),)
Now, we apply the desired animations by accessing the effects property.
effects: [ FadeEffect(), ShakeEffect() ],
effects is a List<Effect<dynamic>> which takes values of Effects that you wish to apply to the widget.
b. Using .animate( ) extension
Without wrapping the widget in another widget, we can simply use an animate( ) extension. This is how its done
Text(
'Animated Widget',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold
)
).animate()
Now, you can further follow up with other extensions to add your desired effects.
.animate()
.shake(duration: const Duration(seconds: 1))
.fade(duration: const Duration(seconds: 1))
You can also use then( ) function to apply effects in sequence.
.animate()
.shake(duration: const Duration(seconds: 1))
.then()
.tint(color: Colors.orange, duration: const Duration(seconds: 1))
The block of code above first applies a shake effect and then paints it with Colors.orange using the tint( ) effect.
This is how the text animates.
delay | Amount of time after which the animation begins. |
duration | Period of time over which the animation lasts. |
curve | Animation curve specified like Curves.linear, Curves.easeIn and many more. |
begin | Initial opacity of the animating widget. By default 0. |
end | Final opacity of the animating widget. By default 1. |
2. Building a Splash Screen
Now, that we know how to animate a widget in Flutter, let us apply animation to build a splash screen in Flutter!
First, let’s start by building a screen. We create a stateless widget named SplashScreen. We will return a Scaffold here, which will be our splash screen.
class SplashScreen extends StatelessWidget {
const SplashScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
We will build a simple splash screen here, with a title in the center. You can design the splash screen as you like!
return Scaffold(
body: Center(
child: const Text(
'News App',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold
),
),
),
);
Selecting the above text style is a creative design choice, you can create a splash screen of your own liking.
Now, we want our splash screen to animate the title and then move to the home screen or the next screen of the app. We can accomplish this by using the Animate( ) widget as we discussed.
Let us wrap our text in Animate( ) widget.
Animate(
autoPlay: true,
effects: const [
FadeEffect(duration: Duration(seconds: 5))
],
child: const Text(
'News App',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold
),
),
),
Since we want to navigate to a new screen as the animation ends, we use the onComplete( ) function to check the state of the animation using a controller and then move to the new screen.
onComplete: (controller) {
if(controller.isCompleted){
Navigator.of(context)
.popAndPushNamed(
HomeScreen.routeName
);
}
},
As the animation ends, we move to the home screen. We use a named route here to navigate to the desired screen.
Thus, the entire code looks like this:
import 'package:animate_flutter/screens/home_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
class SplashScreen extends StatelessWidget {
const SplashScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Animate(
autoPlay: true,
effects: const [
FadeEffect(duration: Duration(seconds: 5))
],
onComplete: (controller){
if(controller.isCompleted){
Future.delayed(const Duration(seconds: 2));
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (ctx)=> const HomeScreen()), (route) => false);
}
},
child: const Text(
'News App',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold
),
),
),
),
);
}
}
Here is what our splash screen looks like:
3. Adding hero animation.
Hero animation is one of the coolest animations supported by Flutter. A hero animation makes the selected widget on a screen, fly to the other screen. A glimpse of the video below will provide more clarity.
When looked closely, the search icon on the home screen, when tapped, remains on the screen flies to the search screen, and lands on the search bar.
Let’s look at implementing this hero animation.
a. Using Hero( ) widget.
Select the widget you want to animate and wrap the widget with a Hero( ) widget.
It is also important to note that the widget you want to animate, must be present in both the screens you want to animate to. In our use case, our widget is present in both, the home screen and the search screen as well. Thus, wrap the widget as below
Hero(
child: IconButton(
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (ctx) => const
SearchScreen()));
},
icon: const Icon(Icons.search)
),
)
b. Add a tag
It is important to provide a tag to our hero widget. This tag is used by Flutter to identify the widget to animate over the two screens.
Hero(
tag: 'Search',
child: IconButton(
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (ctx) => const
SearchScreen()));
},
icon: const Icon(Icons.search)
),
)
Make sure to add the same tag in both the hero widgets lying on two different screens.
4. Reactive Animation
While the data is fetched from the internet, the user might have to face a blank screen while waiting for the data.
Rather than a blank screen, it is a better practice to show the progress of the data being loaded or fetched from the internet. Let’s look at the code below.
FutureBuilder(
future: NewsApi.getNews(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
final List<NewsArticle> news = snapshot.data;
// Return your data here.
} else if (snapshot.hasError) {
return Center(child: Text(snapshot.error.toString()));
}
}),
In the code above, we use FutureBuilder( ). FutureBuilder( ) is a widget in Flutter that allows you to listen to asynchronous snapshots of data. These snapshots also allow you to access the state of the connection. NewsApi.getNews( ), is a function that returns our future.
Using the connection state from the snapshot of data, we can implement our animation, to occupy the screen as the data is being fetched in the background.
else if(snapshot.connectionState
== ConnectionState.waiting){
return Center(
child: Animate(
effects: const [
ShakeEffect()
],
autoPlay: true,
onComplete: (controller){
controller.repeat(reverse: true);
},
child: const Text('Loading...', style: TextStyle(fontSize: 20),),
),
);
}
Here, we check for the connectionState of the snapshot. If the ConnectionState.waiting is true, we display an animating text widget in the center of the screen.
We access the onComplete( ) function of the animate widget, to repeat the animation till the connection state is still waiting.
Here is what our reactive animation looks like in the search screen of our news application.
5. Project code and resources.

Prithviraj Kapil
Hi! I’m Prithviraj Kapil, a passionate coder, app developer, and technical creative writer. I work with android and flutter. I like to develop mobile apps and create art. I am currently an undergraduate student and I have started contributing to Developers Breach with a motive to share my knowledge with others.
Here We Go Again : (
if (article == helpful) {
println("Like and subscribe to blog newsletter.")
} else {
println("Let me know what i should blog on.")
}
Leave a Reply