如何在 Flutter 的 AnimationController 中添加 Curves class 动画?
How do you add a Curves class animation to AnimationController in Flutter?
我正在尝试将曲线 class 动画 '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' 动画,使容器在点击时弹跳?
在此先感谢您的帮助!
您需要同时使用动画控制器和补间,这样您就可以添加 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;
}
}
});
一个更简洁的方法是只使用 controller.drive()
和 CurveTween
:
anim = animController.drive(CurveTween(curve: Curves.easeOut));
然后在您的小部件树中使用 anim.value
。
如果需要,也可以内联执行此操作:
Opacity(opacity: controller.drive(CurveTween(curve: Curves.easeOut)).value)
我正在尝试将曲线 class 动画 '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' 动画,使容器在点击时弹跳?
在此先感谢您的帮助!
您需要同时使用动画控制器和补间,这样您就可以添加 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;
}
}
});
一个更简洁的方法是只使用 controller.drive()
和 CurveTween
:
anim = animController.drive(CurveTween(curve: Curves.easeOut));
然后在您的小部件树中使用 anim.value
。
如果需要,也可以内联执行此操作:
Opacity(opacity: controller.drive(CurveTween(curve: Curves.easeOut)).value)