When working with any mobile application you'll likely be in a position when you want to animate some text based on some application state. Flutter makes this easy with the use of AnimatedDefaultTextStyle, and we'll be looking at how to change between two states below.

https://www.youtube.com/watch?v=fL2xleovE8A

This is what we'll be building:

animate

Want a video version of this article? Here you go!

Project setup

As always, let's create a blank project that we can use as a starting point:

$ flutter create animated_text && cd animated_text

$ code .

We can then do all of our work inside of a HomePage Widget that we'll define in a moment. Starting at main.dart, update this to provide HomePage to the MaterialApp:

import 'package:animated_text/pages/home.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: HomePage());
  }
}

Next up, we'll create the HomePage at pages/home.dart. This will be a StatefulWidget as we'll be managing the change of state between our animations:

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);

  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Home"),
      ),
      body: Center(
        child: Container(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text("Hello, Flutter")
            ],
          ),
        ),
      ),
    );
  }
}

Animating the text

When it comes down to it, the stages of our animation is as follows:

  1. Check a boolean to see if the animation should play
  2. Change the style based on the status of our boolean

We can achieve this by firstly creating an bool isSelected inside of our _HomePageState

class _HomePageState extends State<HomePage> {
  bool isSelected = false;

  //
}

Then, inside of our Column we can return an AnimatedDefaultTextStyle with the style which returns a TextStyle based on whether isSelected is true or false:

child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
  AnimatedDefaultTextStyle(
    style: isSelected
        ? TextStyle(
            fontSize: 50,
            color: Colors.red,
            fontWeight: FontWeight.bold)
        : TextStyle(
            fontSize: 24.0,
            color: Colors.black,
            fontWeight: FontWeight.w100),
    duration: const Duration(milliseconds: 200),
    child: Text("Animate me!"),
  ),
])

We're also setting the duration here to 200ms, but without a way to change the state isSelected, it's a little useless. Let's add a FlatButton that does this:

FlatButton(
  child: Text("Click me!"),
  onPressed: () {
    setState(() {
      isSelected = !isSelected;
    });
  },
)

Tada! We should now be able to see our text animate backward and forwards. We can also change how the animation works with the curve feature, for example:

AnimatedDefaultTextStyle(
  curve: Curves.bounceInOut
);

There are a multitude of Curves available, and I'd recommend having a play with a few to get a feel for the differences.

Hope you found this article useful!