The album

The design of Flutter Dojo

Flutter Dojo design approach — Build a sound open source project using Github

How to design Flutter Dojo – How to implement the Flutter screen animation

Flutter Dojo Design Approach — How to create a universal Playground


This article is an analysis of the implementation of Flutter animation, using a simple animation, analyze the general steps of Flutter creation animation

The flash screen actually does two things.

  • Propaganda. Through Logo, advertising and other forms, at the start of the display to promote the advertising and other content.
  • Background initialization. Use this time to do some background work and initialize some SDK or code.

Flutter Dojo’s flash animation is a reference to the App splash screen of the famous website P, which should be familiar to everyone.

The animation is actually quite simple, just a drawing from the sides to the middle of the animation.

Generally speaking, there are several steps to create a Flutter animation.

  1. Creating a Static layout
  2. Create Tween to mark the starting value of the animation
  3. Add AnimatedBuilder to static code to drive animation

The static layout

This layout should not be too difficult. There are many ways to implement this effect, such as center-row, which centers the Flutter Text and Dojo Text in the Row. Or you can do stack-positioned, by the left and the right.

C-row is a little bit more intuitive, so I’m going to do this in stack-positioned form.

Whichever scheme you use, it is important to note that the Flutter Text and Dojo Text are collectively centered, not individually centered. Because the Flutter Text is longer than Dojo Text, centering along the center line of the screen will be incongruously.

In addition to the layout, we need to mention a little bit about the implementation of Dojo Text, which is actually implemented through BoxDecoration, as shown below.

decoration: BoxDecoration(
  borderRadius: BorderRadius.circular(8),
  color: Color.fromARGB(255, 253, 152, 39),
),
Copy the code

Define the animation

The animation here is split into two parts, left and right. If you use center-row, the two Text lines do not line up in the middle of the screen, so there is an offset, which is then offset by transform.translate. The other way, stack-positioned, actually does the same thing, but can be animated by the left and the right of tourists.

So the first step is to get the width difference between the Flutter Text and the Dojo Text. There are several ways to get the Size of a Widget.

  • LayoutBuilder. This is not a good solution because the animation needs to be created ahead of time.
  • TextPainter. For text, you can use TextPainter to measure text.
  • The Key. Get the Size of the Widget by retrieving the RenderBox via the Key.

The Key method is relatively easy, so I’m going to use the TextPainter method here. The following function shows how to get the computed width of Text for a particular TextStyle.

double getTextWidth(String text) {
  final textPainter = TextPainter(
    text: TextSpan(
      text: text,
      style: TextStyle(
        fontSize: 60,
        fontWeight: FontWeight.w600,
      ),
    ),
    textDirection: TextDirection.ltr,
  );
  textPainter.layout(minWidth: 0, maxWidth: double.infinity);
  return textPainter.width;
}
Copy the code

By simple calculation, the offset of Flutter Text and Dojo Text is actually half the width difference between the two texts.

Because I have used the position of stack-positioned, the animation also needs to be defined in terms of the static position.

Start with the animation of the Flutter Text. It acts on the left side of the screen with an offset in the middle, so its animation values range from:

begin: screenWidth, end: screenWidth / 2 - offset
Copy the code

Similarly, the Dojo Text animation is similar:

begin: screenWidth, end: screenWidth / 2 + offset
Copy the code

Animation management

The Tween is already determined after the range of the animation values is determined. Here is a technique for animation management. It is possible to decouple the animation logic from the Widget by encapsulating the different Tween values required by the Widget with a class, as shown below.

import 'package:flutter/material.dart';

class SplashAnimManager {
  final AnimationController controller;
  final Animation<double> animLeft;
  final Animation<double> animRight;
  final double screenWidth;
  final double offset;

  SplashAnimManager(this.controller, this.screenWidth, this.offset)
      : animLeft = Tween(begin: screenWidth, end: screenWidth / 2 - offset).animate(
          CurvedAnimation(
            parent: controller,
            curve: Curves.easeIn,
          ),
        ),
        animRight = Tween(begin: screenWidth, end: screenWidth / 2 + offset).animate(
          CurvedAnimation(
            parent: controller,
            curve: Curves.easeIn,
          ),
        );
}
Copy the code

Just to illustrate the idea of animation management, only two animations have been written in the management class.

In fact, there are many places to learn about Flutter Dojo. Not only can you learn about Flutter from the App, but you can find more by reading the Dojo source code.

Animation assembly

Finally, it is assembled by AnimatedBuilder. In fact, the essence of animation is to constantly modify the value of a certain attribute to produce the effect of animation. The same applies to Flutter Text and Dojo Text. In the case of Flutter Text, the right property changes from begin to end of the Tween, so apply the AnimatedBuilder to the static layout. Then set the Tween value for the corresponding property, as shown below.

@override
Widget build(BuildContext context) {
  final double screenWidth = MediaQuery.of(context).size.width;
  _splashAnimManager = SplashAnimManager(
    _animationController,
    screenWidth,
    (getTextWidth('Flutter') - getTextWidth('Dojo') - 4) / 2,
  );
  return Container(
    alignment: Alignment.center,
    color: Colors.black,
    child: Stack(
      fit: StackFit.expand,
      alignment: Alignment.center,
      children: <Widget>[
        AnimatedBuilder(
          animation: _animationController,
          builder: (context, widget) {
            return Positioned(
              right: _splashAnimManager.animLeft.value,
              child: Text(
                'Flutter',
                style: TextStyle(
                  fontSize: 60,
                  color: Colors.white,
                  fontWeight: FontWeight.w600,
                ),
              ),
            );
          },
        ),
        AnimatedBuilder(
          animation: _animationController,
          builder: (context, widget) {
            return Positioned(
              left: _splashAnimManager.animRight.value,
              child: Container(
                padding: EdgeInsets.symmetric(
                  horizontal: 4,
                ),
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(8),
                  color: Color.fromARGB(255, 253, 152, 39),
                ),
                child: Text(
                  'Dojo',
                  style: TextStyle(
                    fontSize: 60,
                    fontWeight: FontWeight.w600,
                    color: Colors.black,
                  ),
                ),
              ),
            );
          },
        ),
      ],
    ),
  );
}
Copy the code

Above, a SAO qi flash screen animation is completed.

The code address

Github.com/xuyisheng/f…

Cultivate immortality

Since the Flutter Dojo is open source, it has been enjoyed by many Flutter learners and enthusiasts. More and more people have joined the Flutter study, so I started a Flutter community, but there were too many people. Therefore, there are three groups of “Guide to Flutter” [North] [East]. If you are interested in Flutter, you can add my wechat account and indicate that you want to join the Flutter group, or directly follow my wechat public account [Android Group English].

If you are interested, please add me to wechat [Tomcat_xu] and I will join you in the group.

Project Address:

Github.com/xuyisheng/f…