flutter package推荐simple_animations

144 阅读2分钟

simple_animations简化了创建精美自定义动画的过程:

  • 在无状态小部件中轻松创建自定义动画
  • 一次为多个属性设置动画
  • 在几秒钟内创建交错动画
  • 简化了AnimationController实例的使用
  • 调试动画

快速开始

Animation Builder

通过Animation Builder可以轻松创建自定义动画。

import 'dart:math';

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

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

  @override
  Widget build(BuildContext context) {
    // PlayAnimationBuilder plays animation once
    return PlayAnimationBuilder<double>(
      tween: Tween(begin: 100.0, end: 200.0), // 100.0 to 200.0
      duration: const Duration(seconds: 1), // for 1 second
      builder: (context, value, _) {
        return Container(
          width: value, // use animated value
          height: value,
          color: Colors.blue,
        );
      },
      onCompleted: () {
        // do something ...
      },
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    // LoopAnimationBuilder plays forever: from beginning to end
    return LoopAnimationBuilder<double>(
      tween: Tween(begin: 0.0, end: 2 * pi), // 0° to 360° (2π)
      duration: const Duration(seconds: 2), // for 2 seconds per iteration
      builder: (context, value, _) {
        return Transform.rotate(
          angle: value, // use value
          child: Container(color: Colors.blue, width: 100, height: 100),
        );
      },
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    // MirrorAnimationBuilder plays forever: alternating forward and backward
    return MirrorAnimationBuilder<Color?>(
      tween: ColorTween(begin: Colors.red, end: Colors.blue), // red to blue
      duration: const Duration(seconds: 5), // for 5 seconds per iteration
      builder: (context, value, _) {
        return Container(
          color: value, // use animated value
          width: 100,
          height: 100,
        );
      },
    );
  }
}

MovieTween

MovieTween可以将多个Tween合并成一个,包括时间线控制和值外推。

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

// Simple staggered tween
final tween1 = MovieTween()
  ..tween('width', Tween(begin: 0.0, end: 100),
          duration: const Duration(milliseconds: 1500), curve: Curves.easeIn)
      .thenTween('width', Tween(begin: 100, end: 200),
          duration: const Duration(milliseconds: 750), curve: Curves.easeOut);

// Design tween by composing scenes
final tween2 = MovieTween()
  ..scene(
          begin: const Duration(milliseconds: 0),
          duration: const Duration(milliseconds: 500))
      .tween('width', Tween<double>(begin: 0.0, end: 400.0))
      .tween('height', Tween<double>(begin: 500.0, end: 200.0))
      .tween('color', ColorTween(begin: Colors.red, end: Colors.blue))
  ..scene(
          begin: const Duration(milliseconds: 700),
          end: const Duration(milliseconds: 1200))
      .tween('width', Tween<double>(begin: 400.0, end: 500.0));

// Type-safe alternative
final width = MovieTweenProperty<double>();
final color = MovieTweenProperty<Color?>();

final tween3 = MovieTween()
  ..tween<double>(width, Tween(begin: 0.0, end: 100))
  ..tween<Color?>(color, ColorTween(begin: Colors.red, end: Colors.blue));

AnimationMixin

AnimationMixin管理AnimationController,不再需要实现复杂的样板代码。

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

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

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

// Add AnimationMixin
class _MyWidgetState extends State<MyWidget> with AnimationMixin {
  late Animation<double> size;

  @override
  void initState() {
    // The AnimationController instance `controller` is already wired up.
    // Just connect with it with the tweens.
    size = Tween<double>(begin: 0.0, end: 200.0).animate(controller);

    controller.play(); // start the animation playback

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: size.value, // use animated value
      height: size.value,
      color: Colors.red,
    );
  }
}

Animation Developer Tools(调试工具)

Animation Developer Tools可以帮助开发者逐步创建或检查动画。非常好用。

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

void main() => runApp(const MaterialApp(home: Scaffold(body: MyPage())));

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

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      // put DevTools very high in the widget hierarchy
      child: AnimationDeveloperTools(
        child: Center(
          child: PlayAnimationBuilder<double>(
            tween: Tween<double>(begin: 0.0, end: 100.0),
            duration: const Duration(seconds: 1),
            developerMode: true, // enable developer mode
            builder: (context, value, child) {
              return Container(
                width: value,
                height: value,
                color: Colors.blue,
              );
            },
          ),
        ),
      ),
    );
  }
}

库链接:simple_animations