如何在 Flutter 中向 AnimationController 添加 Curves 类动画?
Posted
技术标签:
【中文标题】如何在 Flutter 中向 AnimationController 添加 Curves 类动画?【英文标题】:How do you add a Curves class animation to AnimationController in Flutter? 【发布时间】:2019-08-17 05:50:58 【问题描述】:我正在尝试将曲线类动画“Curves.bounceOut”添加到使用 AnimationController 的代码中。
这是我的代码:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
home: MyHomePage(),
);
class MyHomePage extends StatefulWidget
_MyHomePageState createState() => _MyHomePageState();
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin
var squareScale = 1.0;
static AnimationController _controller;
@override
void initState()
_controller = AnimationController(
vsync: this,
lowerBound: 0.5,
upperBound: 1.0,
duration: Duration(milliseconds: 300));
_controller.addListener(()
setState(()
squareScale = _controller.value;
);
);
super.initState();
@override
void dispose()
_controller.dispose();
super.dispose();
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text("Bounce Example"),
),
body: Stack(
children: <Widget>[
Container(
width: 150.0,
height: 150.0,
color: Colors.yellowAccent,
),
Column(
children: <Widget>[
Row(
children: <Widget>[
GestureDetector(
onTap: ()
_controller.forward(from: 0.0);
,
child: Transform.scale(
scale: squareScale,
child: Container(
width: 150.0,
height: 150.0,
color: Colors.green,
),
),
),
],
),
],
),
],
),
);
目前,绿色容器的动画从 0.5 缩放到 1.0 缩放,但不会反弹。如何添加“Curves.bounceOut”动画,以便容器在点击时弹跳?
提前感谢您的帮助!
【问题讨论】:
见CurvedAnimation
我已经看到了 CurvedAnimation 类,但我不知道如何将它正确地包含在我的代码中。
而不是_controller.addListener
使用_curvedAnimation.addListener
?
【参考方案1】:
您需要同时使用动画控制器和补间,这将允许您添加Curves.bounceOut
。
在代码中的某处添加:
AnimationController _controller;
var scaleAnimation;
在你的initState()
方法中:
_controller = new AnimationController(
duration: new Duration(milliseconds: 300),
vsync: this
)
..addListener(()
setState(() );
);
scaleAnimation = new Tween(
begin: 0.5,
end: 1.0,
).animate(new CurvedAnimation(
parent: _controller,
curve: Curves.bounceOut
));
注意..addListener()
是一段不错的 dart 代码,可让您轻松添加侦听器。 Tween 基本上是在告诉您的动画,它需要在AnimationController
给定的时间范围内从begin
中的值变为end
中的值。要在您的代码中使用此值,您现在只需设置动画结果的比例:
child: Transform.scale(
scale: scaleAnimation.value,
child: Container(
width: 150.0,
height: 150.0,
color: Colors.green,
),
),
当动画被调用时,它会自动更新容器的比例。
编辑:
将您的小部件更改为:
child: isChanging ? Transform.scale(
scale: scaleAnimation.value,
child: Container(
width: 150.0,
height: 150.0,
color: Colors.green,
),
) : Transform.scale(
scale: 1.0,
child: Container(
width: 150.0,
height: 150.0,
color: Colors.green,
),
),
将begin
和end
参数分别保留为0.5
和1.0
,但在转发控制器之前在onTap()
方法中添加:
onTap: ()
setState(()
isChanging = true
);
_controller.forward(from: 0.0);
在代码中的任何位置添加bool isChanging
行。最后,您需要在动画结束时重置显示的小部件,因此将 scaleAnimation 更改为:
child: Transform.scale(
scale: scaleAnimation.value,
child: Container(
width: 150.0,
height: 150.0,
color: Colors.green,
),
)..addStatusListener((AnimationStatus status)
if (status == AnimationStatus.completed) //the animation is finished
_controller.reset();
setState(()
isChanging = false;
);
【讨论】:
感谢这工作!你知道在触发任何动画之前如何让容器以 150.0 x 150.0 的宽度开始吗?现在它从 0.5 开始,而不是 1.0。 您可以在scaleAnimation
中交换begin
和end
参数。这将使规模从1.0
开始并变得越来越小。希望这会有所帮助!
抱歉,我可能不够清楚。每次点击容器时,我希望动画从 0.5 变为 1.0。但是,当应用程序首次启动时,容器以 0.5 的比例开始,我希望它以 1.0 的比例开始,然后在点击时直接跳转到 0.5 并动画到 1.0。这可能吗?再次感谢您的帮助。
@hello_friend 有可能......你必须将begin
和end
参数both 设置为1.0,然后让你的曲线成为一部分sin(x)
曲线。然而,即便如此,动画也不会立即从 1.0 跳到 0.5。可能你可以在小部件所在的位置有一个条件语句,如果布尔值为真,那么它会显示容器的 1.0 比例,然后当你单击按钮时它会将其设置为假,将小部件更改为比例为 0.5 的小部件然后在该小部件上运行动画。如果您需要我将其添加到我的答案中,请告诉我。
如果您将此添加到您的答案中,那就太好了。【参考方案2】:
更简洁的方法是使用controller.drive()
和CurveTween
:
anim = animController.drive(CurveTween(curve: Curves.easeOut));
然后在您的小部件树中使用anim.value
。
如果你愿意,也可以内联:
Opacity(opacity: controller.drive(CurveTween(curve: Curves.easeOut)).value)
【讨论】:
以上是关于如何在 Flutter 中向 AnimationController 添加 Curves 类动画?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter 的 Firestore 中向数组中添加相等的元素?
在 Flutter 中向 CarouselSlider Widget 显示 JSON 数据