Implicit vs Explicit Animation in Flutter

Certainly the choice is ours. But we get confused so easily. When the question is on the Implicit Animation vs the Explicit Animation in Flutter, we cannot decide. Which one is right for us?

Well, do not procrastinate. Delaying is not a good idea. Choose any one. However, before that, we should know both animations.

What is implicit animation in Flutter?

Implicit Animation is much faster than the Explicit Animation.

Why?

Because the Implicit Animation comes with Flutter. The implicitly animated widgets ship with the Flutter-Framework. We do not have to tell the Flutter-Framework what to do. It knows its job.

In addition, we can avoid the Stateful Widget. Subsequently, we can manage the State of Animation by Provider Package. Or, by some other State Management mechanism.

What is explicit animation in Flutter?

On the contrary, the Explicit animations uses the Stateful Widget. It rebuilds the Widget tree. As a result it uses more system resource. The Explicit Animation tells the Flutter-Framework how to animate.

In Implicit Animation we do not have more controls. But in Explicit Animation we have more controls. We can customise our Animations.

Therefore exercise prudence. We need to decide which Animation is better for our Flutter Application.

Implicit vs Explicit Animation

Let us see the Implicit Animation and Explicit Animation in one place. We have a Text Widget that changes its color.

In the Implicit Animation we set a target value. When we press the ElevatedButton Widget, the color of the Text Widget changes from red to blue.

On the other hand, the Explicit Animation changes the color of Text from green to purple in 1 second. We do not have to press any Button to get the effect.

Implicit vs Explicit Animation
Implicit and Explicit Animation in Flutter in one place

Now, let us look separately at the code of the Implicit Animation and the Explicit Animation.

Firstly, let us build an Implicit Animation with the help of Provider package.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class ChangeTextStyle with ChangeNotifier {
  TextStyle targetTextStyle = const TextStyle(
    color: Colors.red,
    fontSize: 25.0,
    fontWeight: FontWeight.bold,
  );
  void changeTextStyle() {
    targetTextStyle = targetTextStyle ==
            const TextStyle(
              color: Colors.red,
              fontSize: 25.0,
              fontWeight: FontWeight.bold,
            )
        ? const TextStyle(
            color: Colors.blue,
            fontSize: 25.0,
          )
        : const TextStyle(
            color: Colors.red,
            fontSize: 25.0,
            fontWeight: FontWeight.bold,
          );
    notifyListeners();
  }
}

void main() {
  Provider.debugCheckInvalidValueType = null;
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => ChangeTextStyle()),
      ],
      child: const MyApp(),
    ),
  );
}

We need to provide the target value to the Child Widget inside the Widget tree.

Therefore, we have built a Model class that has a target value and a method that changes the target value.

On the other hand, the Explicit Animation rapidly rebuilds the Widget tree.

Subsequently, we can keep them inside a Column Widget.

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Animated TextStyle';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      debugShowCheckedModeBanner: false,
      home: Scaffold(
          appBar: AppBar(title: const Text(_title)),
          body: Column(
            children: const [
              ImplicitTextStyleAnimation(),
              SizedBox(
                height: 20.0,
              ),
              ExplicitTextStyleAnimation(),
            ],
          )),
    );
  }
}

The code of Implicit Animation

When we press the ElevatedButton, the Widget animates the property from the old value to the new one.

By this way, the Implicit Animation manages the Animation effect.

We do not have to manage the animation.

class ImplicitTextStyleAnimation extends StatelessWidget {
  const ImplicitTextStyleAnimation({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    ChangeTextStyle _targetTextStyleChange = Provider.of(context);
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        AnimatedDefaultTextStyle(
          style: _targetTextStyleChange.targetTextStyle,
          duration: const Duration(seconds: 1),
          curve: Curves.easeInOut,
          child: const Text('Implicit Animation'),
        ),
        ElevatedButton(
            child: const Text('Change TextStyle'),
            onPressed: () {
              _targetTextStyleChange.changeTextStyle();
            }),
      ],
    );
  }
}

In the above code the Implicit Animation Widget the AnimatedDefaultTextStyle takes the target value as its “style” argument.

The AnimatedDefaultTextStyle is an Animated version of DefaultTextStyle. The DefaultTextStyle transitions the default TextStyle over a given duration whenever we press the ElevatedButton.

The textAlignsoftWrapoverflow  and some other properties are not animated though. However, they change if we want to use them.

The code of Explicit Animation

If we compare, we will find that the Explicit Animation has a set of controls. Using those controls we can tell Flutter how to rebuild the Widget.

When the Widget rebuilds, the properties of the Widget change. As a consequence, the change creates animation effects.

class ExplicitTextStyleAnimation extends StatefulWidget {
  const ExplicitTextStyleAnimation({Key? key}) : super(key: key);

  @override
  State<ExplicitTextStyleAnimation> createState() =>
      _ExplicitTextStyleAnimationState();
}

class _ExplicitTextStyleAnimationState extends State<ExplicitTextStyleAnimation>
    with TickerProviderStateMixin {
  late AnimationController _controller;
  late TextStyleTween _styleTween;
  late CurvedAnimation _curvedAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 1),
      vsync: this,
    )..repeat(reverse: true);
    _styleTween = TextStyleTween(
      begin: const TextStyle(
        fontSize: 25,
        color: Colors.green,
        fontWeight: FontWeight.bold,
      ),
      end: const TextStyle(
        fontSize: 25,
        color: Colors.deepPurple,
      ),
    );
    _curvedAnimation = CurvedAnimation(
      parent: _controller,
      curve: Curves.bounceInOut,
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: DefaultTextStyleTransition(
        style: _styleTween.animate(_curvedAnimation),
        child: const Text('Explicit TextStyle'),
      ),
    );
  }
}

As we can see that the Explicit Animation gives us more options. Although it uses more system resources, still we cannot achieve this with the Implicit Animation.

We have defined three Animation Widgets separately. The AnimationController, the TextStyleTween and the CurvedAnimation. Then we combine them to make the animation effect.

After that, we have used the DefaultTextStyleTransition and pass that combination of explicitly defined animations to its “style” argument.

The DefaultTextStyleTransition is the Explicitly Animated version of a DefaultTextStyle. As we customise, the DefaultTextStyle animates the different properties of its TextStyle.

To get the full code in one place, please visit the respective GitHub Repository.

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

Courses at Educative

GitHub repository

Technical blog

Twitter

Comments

One response to “Implicit vs Explicit Animation in Flutter”

  1. […] The animated text kit package makes our life easier because we don’t have to build the animation from scratch. […]

Leave a Reply