[Flutter Actual Combat] More than 20 animation components in a literary meeting

Lao Meng's guide: This article is the third article in the Flutter animation series, followed by animation sequences, transition animations, transition animations, custom animations, etc.

The Flutter system provides more than 20 animation components. As long as you understand the article on [Animation Core] (link at the end of the article), these components are very easy for you. Most of these components are for common operations. Package.

Show animation components

Review the three necessary steps for creating animation in the last article [Animation Core]:

  1. Create AnimationController.
  2. Monitor AnimationController, calling setStaterefresh UI.
  3. Release the AnimationController.

Look at the second step, every animation needs this step, so it is packaged and named MyAnimatedWidget:

class MyAnimatedWidget extends StatefulWidget {
  final AnimationController controller;
  final Widget child;

  const MyAnimatedWidget(
      {Key key, @required this.controller, @required  this.child})
      : super(key: key);

  @override
  _MyAnimatedWidgetState createState() => _MyAnimatedWidgetState();
}

class _MyAnimatedWidgetState extends State<MyAnimatedWidget> {
  @override
  void initState() {
    super.initState();
    widget.controller.addListener(() {
      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    return widget.child;
  }

  @override
  void dispose() {
    super.dispose();
    widget.controller.dispose();
  }
}

The custom animation component has only two functions:

  1. Listen to AnimationController and call setState.
  2. Release the AnimationController.

The creation of AnimationController needs to be created by the developer. Why is it encapsulated in a custom component? This will be introduced later.

In fact, this component does not need to be encapsulated by ourselves, because the system is already encapsulated. It is very important to customize the component in the process of learning Flutter. Therefore, encapsulate more components, even if the system already exists, compare it with your own. Can greatly improve our ability to customize components.

The component similar to the above encapsulated by the system is AnimatedWidget , which is an abstract class, source code:

the difference:

  1. We use to listen to AnimationController, call setState, and the system uses Listenable , Listenable is an object that maintains a list of listeners, used to notify the client that the object has been updated.

    There are two variants of Listenable:

    1. ValueListenable : An interface that extends the [Listenable] interface and has the concept of current values.
    2. Animation : An interface that extends the [ValueListenable] interface, adding the concept of direction (forward or reverse).

    The inheritance structure of AnimationController:

    AnimationController also inherits from Listenable, so the use of Listenable is applicable to a wider range, not only for Animation, but also for ChangeNotifier.

  2. Because Listenable is used, monitoring and release use listenable.addListenerand listenable.removeListener.

AnimatedWidget is an abstract class and cannot be used directly. Its subclasses include:

Take ScaleTransition as an example to use:

class AnimationDemo extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _AnimationDemo();
}

class _AnimationDemo extends State<AnimationDemo>
    with SingleTickerProviderStateMixin {
  AnimationController _animationController;
  Animation _animation;

  @override
  void initState() {
    _animationController =
        AnimationController(duration: Duration(seconds: 2), vsync: this);

    _animation = Tween(begin: .5, end: .1).animate(_animationController);

    //开始动画
    _animationController.forward();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return ScaleTransition(
      scale: _animation,
      child: Container(
        height: 200,
        width: 200,
        color: Colors.red,
      ),
    );
  }

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

The only difference from the writing in [Animation Core] is that it does not need to be called actively setState.

The usage of other subclasses of AnimatedWidget is similar, and they are not introduced one by one. The detailed usage of other components can be viewed in http://laomengit.com/flutter/widgets/widgets_structure.html .

Implicit animation component

AnimatedWidget is just encapsulated setState. Does the system have components that encapsulate AnimationController, Tween, Curve and automatically manage AnimationController? Yes, this component is ImplicitlyAnimatedWidget , and ImplicitlyAnimatedWidget is also an abstract class, and its subclasses include:

Take AnimatedOpacity as an example to use:

class AnimatedWidgetDemo extends StatefulWidget {
  @override
  _AnimatedWidgetDemoState createState() => _AnimatedWidgetDemoState();
}

class _AnimatedWidgetDemoState extends State<AnimatedWidgetDemo> {
  double _opacity = 1.0;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: AnimatedOpacity(
        opacity: _opacity,
        duration: Duration(seconds: 2),
        child: GestureDetector(
          onTap: () {
            setState(() {
              _opacity = 0;
            });
          },
          child: Container(
            height: 60,
            width: 150,
            color: Colors.blue,
          ),
        ),
      ),
    );
  }
}

Using AnimatedOpacity we did not actively create AnimationController and Tween, because AnimatedOpacity has already been created internally.

So don’t look at Flutter’s built-in more than 20 animation components, 90% of which are encapsulation of the above two methods, called implicit animation components and display animation components:

  • Implicit animation components : just provide the start and end values ​​of the component animation, the component creates AnimationController, Curve, Tween, executes the animation, and releases the AnimationController. We call it the implicit animation component. The implicit animation components are: AnimatedAlign , AnimatedContainer , AnimatedDefaultTextStyle , AnimatedOpacity , AnimatedPadding , AnimatedPhysicalModel , AnimatedPositioned , AnimatedPositionedDirectional , AnimatedTheme , SliverAnimatedOpacity , TweenAnimationBuilder , AnimatedContainer, etc.
  • Display animation components : You need to set up AnimationController to control the execution of animations. Use explicit animations to complete any implicit animation effects, and even have more functions. However, you need to manage the animation controller life cycle. AnimationController is not a control, so It needs to be placed in a stateful control. Display animation components are: AlignTransition , AnimatedBuilder , AnimatedModalBarrier , DecoratedBoxTransition , DefaultTextStyleTransition , PositionedTransition , RelativePositionedTransition , RotationTransition , ScaleTransition , SizeTransition , SlideTransition , FadeTransition, etc.

It is not difficult to see that using implicit animation controls makes the code simpler, and there is no need to manage the life cycle of AnimationController. Some people think that implicit animation components are so convenient. Why should animation components be displayed? Because: the more complex the package, the simpler it is to use, and often accompanied by less abundant functions. For example, if you want the animation to be executed repeatedly, the implicit animation component cannot be realized.

There is a universal component in the display animation component and the implicit animation component. They are AnimatedBuilder and TweenAnimationBuilder . When the animation component we want does not exist in the system, these two components can be used. Take AnimatedBuilder as an example to achieve the Container size Animate the color at the same time,

class AnimatedBuilderDemo extends StatefulWidget {
  @override
  _AnimatedBuilderDemoState createState() => _AnimatedBuilderDemoState();
}

class _AnimatedBuilderDemoState extends State<AnimatedBuilderDemo>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;
  Animation<Color> _colorAnimation;
  Animation<Size> _sizeAnimation;

  @override
  void initState() {
    _controller =
        AnimationController(vsync: this, duration: Duration(seconds: 2));

    _colorAnimation =
        ColorTween(begin: Colors.blue, end: Colors.red).animate(_controller);
    _sizeAnimation =
        SizeTween(begin: Size(100.0, 50.0), end: Size(200.0, 100.0))
            .animate(_controller);

    _controller.forward();
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    return Center(
      child: AnimatedBuilder(
        animation: _controller,
        builder: (context, widget) {
          return Container(
            width: _sizeAnimation.value.width,
            height: _sizeAnimation.value.height,
            color: _colorAnimation.value,
          );
        },
      ),
    );
  }
}

AnimatedBuilder and TweenAnimationBuilder are essentially no different from other animation components, but they give us more flexibility.

How to choose

Flutter built-in animation is divided into two components: an implicit animation components and display an animation component , show animation component encapsulates the only setStatemethod requires developers to create AnimationController, and management AnimationController. The implicit animation component encapsulates the AnimationController, Curve, and Tween, and only needs to provide the component animation start and end values, and the rest is managed by the system.

The implicit animation component can complete the effect, and the display animation component can be completed, so when to use the implicit animation component? When to use the display animation component?

  1. Determine whether your animation component has been repeated, such as a loading animation that keeps spinning, if it is an explicit animation.
  2. Determine whether your animation component needs multiple component linkage, if it is to choose explicit animation.
  3. Determine whether your animation components need to be combined animation, if it is to choose explicit animation.
  4. If all the above three conditions are not, then select the implicit animation component to determine whether it has built-in animation component, if not, use TweenAnimationBuilder, if yes, use the built-in animation component directly.
  5. Select an explicit animation component and determine whether it has built-in animation components. If not, use AnimatedBuilder. If there is, use built-in animation components directly.

The logic diagram is as follows:

There is also a simple way to distinguish: if your animation is relatively simple, and the animation transitions from one state to another, you do not need to control the AnimationController separately. In this case, implicit animation components can generally be achieved.

However, there is no need to particularly entangle the use of implicit animation components or display animation components, no matter which one is used, the effect can be achieved.

communicate with

Laomeng Flutter blog address (330 control usage): http://laomengit.com

Welcome to join the Flutter exchange group (WeChat: laomengit) and follow the public account [Lao Meng Flutter]:

Guess you like

Origin blog.csdn.net/mengks1987/article/details/108091702