分享

Flutter 动画依赖包推荐使用

 程序员读书空间 2023-10-17 发布于浙江
simple_animations: ^5.0.2

这个依赖库是用来方便 Flutter开发者快速实现各种动画效果而出现的.

本文章的总分解释文案是由 文客微创 APP 来协助完成的,点击查看原文可以下载,文客微创小程序正在努力上线中...


基本动画效果

比如这里是一个大小缩放的动画

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 ... }, ); }}

执行效果如下:

其实现的本质就是在一定时间内改变 Container的大小。

PlayAnimationBuilder 用来构建基本的动画过程,它是一次性执行,它的构造函数如下

  const PlayAnimationBuilder({    required this.tween,    required this.duration,    required this.builder,    this.delay = Duration.zero,    this.curve = Curves.linear,    this.child,    this.fps,    this.developerMode = false,    this.onStarted,    this.onCompleted,    Key? key,  }) : super(key: key);
  •  tween Animatable 动画的类型,必选

  • duration 动画的执行时间,必选

  • builder 子View构建函数 必选

  • delay 动画延时执行的时间

  • curve 动画变化的曲线模型

  • child 执行动画的子组件

  • onStarted 动画开始执行的回调

  • onCompleted 动画执行完成的回调


LoopAnimation 用来实现循环执行动画效果

比如这里循环执行文字的放大动画 

实现的代码如下:

import 'package:flutter/material.dart';import 'package:simple_animations/simple_animations.dart';
void main() => runApp(const MaterialApp(home: Scaffold(body: Center(child: Page()))));
class Page extends StatelessWidget { const Page({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return LoopAnimationBuilder<double>( tween: Tween(begin: 0.0, end: 10.0), duration: const Duration(seconds: 2), curve: Curves.easeOut, builder: (context, value, child) { return Transform.scale( scale: value, child: child, ); }, child: const Text('Hello!'), ); }}
MirrorAnimation 用来实现镜像动画效果

也是循环执行,与LoopAnimationBuilder不同的是,此处是由开始->结尾->开始 这样循环往复的执行。

代码如下:

import 'package:flutter/material.dart';import 'package:simple_animations/simple_animations.dart';
void main() => runApp(const MaterialApp(home: Scaffold(body: Center(child: Page()))));
class Page extends StatelessWidget { const Page({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return MirrorAnimationBuilder<double>( tween: Tween(begin: -100.0, end: 100.0), // value for offset x-coordinate duration: const Duration(seconds: 2), curve: Curves.easeInOutSine, // non-linear animation builder: (context, value, child) { return Transform.translate( offset: Offset(value, 0), // use animated value for x-coordinate child: child, ); }, child: Container( width: 100, height: 100, color: Colors.green, ), ); }}

在Flutter中,Transform是一种用于进行各种变换的Widget,包括旋转、缩放、平移等操作。这些变换可以通过在Transform中指定相应的属性来实现,例如transform、origin、alignment等。通过使用Transform,可以轻松地实现各种复杂的界面效果。

CustomAnimationBuilder 用来自定义动画效果

它需要一个Control控制器来协作

import 'package:flutter/material.dart';import 'package:simple_animations/simple_animations.dart';
void main() => runApp(const MaterialApp(home: Scaffold(body: Center(child: Page()))));
class Page extends StatelessWidget { const Page({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return CustomAnimationBuilder<double>( control: Control.mirror, tween: Tween(begin: 100.0, end: 200.0), duration: const Duration(seconds: 2), delay: const Duration(seconds: 1), curve: Curves.easeInOut, startPosition: 0.5, animationStatusListener: (status) { debugPrint('status updated: $status'); }, builder: (context, value, child) { return Container( width: value, height: value, color: Colors.blue, child: child, ); }, child: const Center( child: Text('Hello!', style: TextStyle(color: Colors.white, fontSize: 24))), ); }}
结合 Movie Tween 来实现各种组合效果的动画效果

宽度与高度同时从0~100,呈现等比放大的效果,然后宽度由100 ~ 200,就是之后的宽度一下变大的效果。

然后这中间造成视觉差异的就是每一步的时间不一样。

import 'package:flutter/material.dart';import 'package:simple_animations/simple_animations.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { // Specify your tween final MovieTween tween = MovieTween() ..scene( begin: const Duration(milliseconds: 0), end: const Duration(milliseconds: 1000)) .tween('width', Tween(begin: 0.0, end: 100.0)) ..scene( begin: const Duration(milliseconds: 1000), end: const Duration(milliseconds: 1500)) .tween('width', Tween(begin: 100.0, end: 200.0)) ..scene( begin: const Duration(milliseconds: 0), duration: const Duration(milliseconds: 2500)) .tween('height', Tween(begin: 0.0, end: 200.0)) ..scene( begin: const Duration(milliseconds: 0), duration: const Duration(milliseconds: 3000)) .tween('color', ColorTween(begin: Colors.red, end: Colors.blue));
return MaterialApp( home: Scaffold( backgroundColor: Colors.white, body: Center( child: PlayAnimationBuilder<Movie>( tween: tween, // Pass in tween duration: tween.duration, // Obtain duration builder: (context, value, child) { return Container( width: value.get('width'), // Get animated values height: value.get('height'), color: value.get('color'), ); }, ), ), ), ); }}


§§


import 'package:flutter/material.dart';import 'package:simple_animations/simple_animations.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { // Specify your tween final tween = MovieTween() ..tween('x', Tween(begin: -100.0, end: 100.0), duration: const Duration(seconds: 1)) .thenTween('y', Tween(begin: -100.0, end: 100.0), duration: const Duration(seconds: 1)) .thenTween('x', Tween(begin: 100.0, end: -100.0), duration: const Duration(seconds: 1)) .thenTween('y', Tween(begin: 100.0, end: -100.0), duration: const Duration(seconds: 1));
return MaterialApp( home: Scaffold( backgroundColor: Colors.white, body: Center( child: LoopAnimationBuilder<Movie>( tween: tween, // Pass in tween duration: tween.duration, // Obtain duration builder: (context, value, child) { return Transform.translate( // Get animated offset offset: Offset(value.get('x'), value.get('y')), child: Container( width: 100, height: 100, color: Colors.green, ), ); }, ), ), ), ); }}


§§


import 'package:flutter/material.dart';import 'package:simple_animations/simple_animations.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { // Variant with typed properties final x = MovieTweenProperty<double>(); final y = MovieTweenProperty<double>(); final color = MovieTweenProperty<Color?>();
// Specify your tween final tween = MovieTween() ..scene( begin: const Duration(seconds: 0), duration: const Duration(seconds: 1)) .tween(x, Tween(begin: -100.0, end: 100.0), curve: Curves.easeInOutSine) .tween(color, ColorTween(begin: Colors.red, end: Colors.yellow)) ..scene( begin: const Duration(seconds: 1), duration: const Duration(seconds: 1)) .tween(y, Tween(begin: -100.0, end: 100.0), curve: Curves.easeInOutSine) ..scene( begin: const Duration(seconds: 2), duration: const Duration(seconds: 1)) .tween(x, Tween(begin: 100.0, end: -100.0), curve: Curves.easeInOutSine) ..scene( begin: const Duration(seconds: 1), end: const Duration(seconds: 3)) .tween(color, ColorTween(begin: Colors.yellow, end: Colors.blue)) ..scene( begin: const Duration(seconds: 3), duration: const Duration(seconds: 1)) .tween(y, Tween(begin: 100.0, end: -100.0), curve: Curves.easeInOutSine) .tween(color, ColorTween(begin: Colors.blue, end: Colors.red));
return MaterialApp( home: Scaffold( backgroundColor: Colors.white, body: Center( child: LoopAnimationBuilder<Movie>( tween: tween, // Pass in tween duration: tween.duration, // Obtain duration builder: (context, value, child) { return Transform.translate( // Get animated offset offset: Offset(x.from(value), y.from(value)), child: Container( width: 100, height: 100, color: color.from(value), // Get animated color ), ); }, ), ), ), ); }}
与Animation 混合使用

如下效果是一个简单的 放大的效果

import 'package:flutter/material.dart';import 'package:simple_animations/simple_animations.dart';
void main() => runApp(const MaterialApp(home: Page()));
class Page extends StatelessWidget { const Page({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return const Scaffold( body: SafeArea(child: Center(child: MyAnimatedWidget())), ); }}
class MyAnimatedWidget extends StatefulWidget { const MyAnimatedWidget({Key? key}) : super(key: key);
@override _MyAnimatedWidgetState createState() => _MyAnimatedWidgetState();}
// Add AnimationMixin to state classclass _MyAnimatedWidgetState extends State<MyAnimatedWidget> with AnimationMixin { late Animation<double> size; // Declare animation variable
@override void initState() { // The controller is automatically provided by the mixin. // Connect tween and controller and store into animation variable. size = Tween(begin: 0.0, end: 200.0).animate(controller);
// Start the animation playback controller.play(); super.initState(); }
@override Widget build(BuildContext context) { return Container( width: size.value, // Use the value of the animation variable height: size.value, color: Colors.red, ); }}
与结合 AnimationController来使用
import 'package:flutter/material.dart';import 'package:simple_animations/simple_animations.dart';
void main() => runApp(const MaterialApp(home: Page()));
class Page extends StatelessWidget { const Page({Key? key}) : super(key: key);
@override Widget build(BuildContext context) { return const Scaffold( body: SafeArea(child: Center(child: MyAnimatedWidget())), ); }}
class MyAnimatedWidget extends StatefulWidget { const MyAnimatedWidget({Key? key}) : super(key: key);
@override _MyAnimatedWidgetState createState() => _MyAnimatedWidgetState();}
class _MyAnimatedWidgetState extends State<MyAnimatedWidget> with AnimationMixin { // declare AnimationControllers late AnimationController widthController; late AnimationController heightController; late AnimationController colorController;
// declare Animation variables late Animation<double> width; late Animation<double> height; late Animation<Color?> color;
@override void initState() { // create controller instances and use mirror animation behavior widthController = createController() ..mirror(duration: const Duration(seconds: 5)); heightController = createController() ..mirror(duration: const Duration(seconds: 3)); colorController = createController() ..mirror(duration: const Duration(milliseconds: 1500));
// connect tween with individual controllers width = Tween(begin: 100.0, end: 200.0).animate(widthController); height = Tween(begin: 100.0, end: 200.0).animate(heightController); color = ColorTween(begin: Colors.red, end: Colors.blue) .animate(colorController);
super.initState(); }
@override Widget build(BuildContext context) { return Container( width: width.value, // use animated values height: height.value, color: color.value, ); }}

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章