Flutter 基于相同特性的颤振交错动画

Flutter 基于相同特性的颤振交错动画,flutter,animation,dart,flutter-animation,Flutter,Animation,Dart,Flutter Animation,我想为小部件的比例设置动画。 点击向下时,它应按比例缩小,点击向上时,按比例放大 问题是如何在同一属性上使用? 这里有一个关于SO()的老问题,但没有有效的答案 我试图调整其解决方案,但问题是,即使未达到指定的间隔,也会调用每个动画侦听器 我添加了一个条件,用于检查是否设置了\u animationFuture,但使用此模式,您必须为小部件中的任何正在运行的动画保留一个值,这有点麻烦 是否有一个“本机”解决方案,您不需要解决问题,或者不支持相同值的多个动画 我不想反转()动画。每个二者之间必须能

我想为小部件的比例设置动画。 点击向下时,它应按比例缩小,点击向上时,按比例放大

问题是如何在同一属性上使用?
这里有一个关于SO()的老问题,但没有有效的答案

我试图调整其解决方案,但问题是,即使未达到指定的
间隔
,也会调用每个动画侦听器

我添加了一个条件,用于检查是否设置了
\u animationFuture
,但使用此模式,您必须为小部件中的任何正在运行的动画保留一个值,这有点麻烦

是否有一个“本机”解决方案,您不需要解决问题,或者不支持相同值的多个动画

我不想
反转()
动画。每个二者之间必须能够有一个自定义曲线、开始值和结束值

这是我的小部件:


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

  }
}


类animateDictionButton扩展StatefulWidget{
最后一个孩子;
压力机的最终功能;
animateDictionButton({@required this.child,this.onPress}):断言(child!=null);
@凌驾
_AnimateDictionButtonState createState()=>\u AnimateDictionButtonState();
}
类_animateDictionButtonState使用SingleTickerProviderStateMixin扩展状态{
AnimationController _AnimationController;
动画(Animation);;
动画输出;
双刻度=1;
票务未来(动画未来),;
函数get-onPress=>widget.onPress()=>null;
_录制(录制详细信息){
打印(“_tappdownprogress=${u animationController.value}scale=$_scale”);
_animationFuture=_animationController.animateTo(0.5);
}
_录制(录制详细信息){
断言(_animationFuture!=null);
打印(“_tappupprogress=${u animationController.value}scale=$_scale”);
_动画未来。然后((){
_animationFuture=null;
_animationController.animateTo(1);
});
}
@凌驾
void initState(){
super.initState();
_animationController=animationController(值:0,vsync:this,持续时间:const duration(毫秒:1500),animationBehavior:animationBehavior.preserve);
_animationIn=Tween(开始:1.0,结束:0.9)。设置动画(曲线动画)(
父项:_animationController,
曲线:区间(
0,0.5,曲线:Curves.easeOut,
),
))…addListener(){
if(_animationFuture==null)返回;
打印(“\u animationIn.value${\u animationOut.value}”);
_比例=_animationIn.value;
});
_animationOut=Tween(开始:0.9,结束:1)。设置动画(曲线动画)(
父项:_animationController,
曲线:区间(
0.5,1,曲线:Curves.elasticOut,
),
))…addListener(){
if(_animationFuture!=null)返回;
打印(“\u animationOut.value${\u animationOut.value}”);
_比例=_animationOut.value;
});
}
@凌驾
无效处置(){
_animationController.dispose();
super.dispose();
}
@凌驾
小部件构建(构建上下文){
返回手势检测器(
onTapUp:_tappup,
onTapDown:_tappdown,
子对象:动画生成器(
动画:_animationController,
child:widget.child,
建筑商:(u,孩子){
返回变换比例(
比例:_比例,
测试结果:错误,
孩子:孩子,
);
},
),
);
}
}