📅  最后修改于: 2021-01-02 05:23:51             🧑  作者: Mango
动画是Flutter中非常重要的概念。我们无法想象没有动画的任何移动应用程序。当您点击按钮或从一页移动到另一页时,所有动画都是。动画可以增强用户体验,并使应用程序更具交互性。
Flutter为动画提供了出色的支持,可以将动画分为两个主要类别,如下所示:
它是中介的简称。在补间动画中,需要定义动画的起点和终点。这意味着动画从起始值开始,然后经过一系列中间值,最后达到结束值。它还提供了时间线和曲线,它们定义了转换的时间和速度。小部件框架提供了有关如何从起点和终点过渡的计算。
ColorTween {
begin: color.green,
end: color.blue,
}
这是一种动画类型,可让您使应用程序交互感觉逼真且互动。它可以模拟现实世界中的动画/运动,例如您要为小部件设置动画,例如弹簧,下落或因重力而摆动。因此,它是响应于用户输入/运动而进行动画处理的动画。最简单的例子是飞行时间,所涵盖的旅行距离将根据物理定律进行计算。
Flutter提供了两种动画技术。这些技术是:
下图列出了Flutter中的动画层次,并更清楚地说明了隐式和显式动画。
现在,我们将看到如何在Flutter中创建显式动画。动画主要包括以下三个支柱:
股票行情指示器是一种以定期间隔(即每秒约60次)发送信号的类。您可以使用手表来了解它,它会定期发出声音。在每次滴答时,滴答声提供了一种回调方法,该方法具有自启动后每秒滴答的持续时间。即使行情自动收录器在不同的时间开始,它始终会自动同步。这背后的原因是,行情自动收录器给出了相对于其开始后的第一个行情的经过时间。
Animation类是动画系统的核心构建块。动画没什么,但是它代表一个值(特定类型),该值可以在动画的整个生命周期内变化。在Flutter中,执行动画的小部件将动画对象作为参数。这个Animation对象提供了从中读取动画当前值以及侦听该值更改的信息。动画类包含两个方法addListener()和addStatusListener() 。动画的值更改时,它将通知所有使用addListener()添加的侦听器。同样,当动画的状态更改时,它会通知所有使用addStatusListener()添加的侦听器。
最常见的动画类是:
动画控制器是允许我们控制动画的类。每当应用程序准备好新框架时,它始终会生成新值。例如,它可以控制动画的开始,停止,前进或重复。一旦创建了动画控制器,我们就可以基于它开始构建其他动画,例如反向动画和弯曲动画。
animcontroller = AnimationController(vsync: this, duration: Duration(milliseconds: 2500));
在这里,duration选项控制动画过程的持续时间,而vsync选项用于优化动画中使用的资源。
使用AnimationController的基本步骤如下:
步骤1:首先,使用诸如duration和vsync之类的参数实例化AnimationController。
步骤2:添加所需的侦听器,例如addListener()或addStatusListener()。
步骤3:开始动画。
步骤4:在侦听器回调方法(例如setState)中执行操作。
步骤5:最后,处理动画。
让我们看一个简单的动画示例,该示例使用动画类和动画控制器。以下示例显示了补间动画,该补间动画给出了动画的开始和终点。打开项目,并在main.dart文件中替换以下代码。
import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Animation',
theme: ThemeData(
// This is the theme of your application.
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State with SingleTickerProviderStateMixin {
Animation animation;
AnimationController animationController;
@override
void initState() {
super.initState();
animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 2500));
animation = Tween(begin: 0.0, end: 1.0).animate(animationController);
animation.addListener((){
setState((){
print (animation.value.toString());
});
});
animation.addStatusListener((status){
if(status == AnimationStatus.completed){
animationController.reverse();
} else if(status == AnimationStatus.dismissed) {
animationController.forward();
}
});
animationController.forward();
}
@override
Widget build(BuildContext context) {
return Center(
child: AnimatedLogo(
animation: animation,
)
);
}
}
class AnimatedLogo extends AnimatedWidget {
final Tween _sizeAnimation = Tween (begin: 0.0, end: 500.0);
AnimatedLogo({Key key, Animation animation}):super(key: key, listenable: animation);
@override
Widget build(BuildContext context) {
final Animation animation = listenable;
return Transform.scale(
scale: _sizeAnimation.evaluate(animation),
child: FlutterLogo(),
);
}
}
输出量
在Android Studio中运行该应用程序时,您将获得输出。在屏幕上,您将看到Flutter徽标正反方向缩放。
当您需要对动画对象应用非线性曲线时,弯曲动画非常有用。因此,它将动画的进度定义为非线性曲线。
CurvedAnimation(parent: animationController, curve: Curves.bounceOut));
让我们通过前面的示例来理解它。要添加曲线,请在android studio中打开前一个应用,然后添加CurvedAnimation而不是animationController 。或替换以下行:
animation = Tween(begin: 0.0, end: 1.0).animate(animationController);
与下面的行。
animation = Tween(begin: 0.0, end: 1.0).animate(animationController);
现在,当您运行该应用程序时,在向前和向后缩放期间,您将看到带有Flutter徽标的弹跳效果。
英雄动画是一种动画,当应用程序转到下一页时,其中一个屏幕的元素会飞到新屏幕。我们可以通过下面的示例来理解它,其中动画采用图标/图像之类的元素,然后在点击图标后,屏幕将跳至下一页。以下示例对其进行了更清晰的说明。
打开Flutter应用程序,然后在main.dart文件中替换以下代码。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Application',
theme: ThemeData(
primarySwatch: Colors.orange,
),
home: HeroAnimation(title: 'Hero Animation'),
);
}
}
class HeroAnimation extends StatefulWidget {
HeroAnimation({Key key, this.title}) : super(key: key);
final String title;
@override
_HeroAnimationState createState() => _HeroAnimationState();
}
class _HeroAnimationState extends State {
Widget _greenRectangle() {
return Container(
width: 75,
height: 75,
color: Colors.green,
);
}
Widget _detailPageRectangle() {
return Container(
width: 150,
height: 150,
color: Colors.red,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: buildDemoWidget(context),
);
}
Widget buildDemoWidget(BuildContext context) {
return Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 30.0,
),
ListTile(
leading: GestureDetector(
child: Hero(
tag: 'hero-rectangle',
child: _greenRectangle(),
),
onTap: () => _gotoDetailsPage(context),
),
title: Text('Tap on the green icon rectangle to analyse hero animation transition.'),
),
],
),
);
}
void _gotoDetailsPage(BuildContext context) {
Navigator.of(context).push(MaterialPageRoute(
builder: (ctx) => Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Hero(
tag: 'hero-rectangle',
child: _detailPageRectangle(),
),
Text('This is a place where you can see details about the icon tapped at previous page.'),
],
),
),
),
));
}
}
输出量
在Android Studio中运行该应用程序时,将显示以下屏幕。
要显示英雄动画,请点击绿色图标,它将立即飞到一个新屏幕,您将在其中获得有关所点击项目的详细信息。