【发布时间】:2020-08-19 11:57:44
【问题描述】:
我想为小部件的比例设置动画。 点击向下它应该缩小,点击向上,放大。
问题是如何在同一属性上使用staggered animations?
SO (Chaining seperate animations that work on the same properties) 上有一个较旧的问题,但没有有效的答案。
我尝试调整其解决方案,但问题是每个动画侦听器都被调用,即使未达到指定的Interval。
我添加了一个条件来检查是否设置了_animationFuture,但是对于这种模式,您必须为小部件中的任何正在运行的动画保留一个值,这有点麻烦。
是否有一个“本机”解决方案,您不需要解决或不支持具有相同值的多个动画?
我不想reverse()动画。每个补间必须能够具有自定义曲线、开始和结束值。
这是我的小部件:
class AnimatedIconButton extends StatefulWidget {
final Widget child;
final Function onPress;
AnimatedIconButton({@required this.child, this.onPress}): assert(child != null);
@override
_AnimatedIconButtonState createState() => _AnimatedIconButtonState();
}
class _AnimatedIconButtonState extends State<AnimatedIconButton> with SingleTickerProviderStateMixin {
AnimationController _animationController;
Animation<double> _animationIn;
Animation<double> _animationOut;
double _scale = 1;
TickerFuture _animationFuture;
Function get onPress => widget.onPress ?? () => null;
_tapDown(TapDownDetails details) {
print("_tapDown progress=${_animationController.value} scale=$_scale");
_animationFuture = _animationController.animateTo(0.5);
}
_tapUp(TapUpDetails details) {
assert(_animationFuture != null);
print("_tapUp progress=${_animationController.value} scale=$_scale");
_animationFuture.then((_) {
_animationFuture = null;
_animationController.animateTo(1);
});
}
@override
void initState() {
super.initState();
_animationController = AnimationController(value: 0, vsync: this, duration: const Duration(milliseconds: 1500), animationBehavior: AnimationBehavior.preserve);
_animationIn = Tween<double>(begin: 1.0, end: 0.9).animate(CurvedAnimation(
parent: _animationController,
curve: Interval(
0, 0.5, curve: Curves.easeOut,
),
))..addListener(() {
if (_animationFuture == null) return;
print("_animationIn.value ${_animationOut.value}");
_scale = _animationIn.value;
});
_animationOut = Tween<double>(begin: 0.9, end: 1).animate(CurvedAnimation(
parent: _animationController,
curve: Interval(
0.5, 1, curve: Curves.elasticOut,
),
))..addListener(() {
if (_animationFuture != null) return;
print("_animationOut.value ${_animationOut.value}");
_scale = _animationOut.value;
});
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapUp: _tapUp,
onTapDown: _tapDown,
child: AnimatedBuilder(
animation: _animationController,
child: widget.child,
builder: (_, child) {
return Transform.scale(
scale: _scale,
transformHitTests: false,
child: child,
);
},
),
);
}
}
【问题讨论】:
标签: flutter animation dart flutter-animation