Flutter 自定义 onTap 缩放效果

Flutter custom onTap scale effect

我想创建自定义 onTap(或 GestureDetector“指示器”提供的任何其他 onTap 回调,其中内容(子项)被缩小并且文本变暗,像这样:

是否已经有该类型动画的预构建包?如果不能,您至少可以修复下面的代码段。

我尝试使用 AnimationControllerTransform.scaleonTap 回调的各种组合创建一个,但它非常没有响应(一直 'stuck')

这是一个基本片段:

 double squareScaleA = 1;
  AnimationController _controllerA;
  @override
  void initState() {
    _controllerA = AnimationController(
        vsync: this,
        lowerBound: 0.9,
        upperBound: 1.0,
        duration: Duration(milliseconds: 100));
    _controllerA.addListener(() {
      setState(() {
        squareScaleA = _controllerA.value;
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: (dp) {
        _controllerA.forward();
      },
      onTapUp: (dp) {
        _controllerA.reverse();
      },
      child: Transform.scale(
        scale: squareScaleA,
        child: widget.child,
      ),
    );
  }

你可以试试这个酒吧包。您可以根据需要更改动画。使用 scaleCoefficient 你可以调整速度。如果你用它包裹 So 小部件,它看起来会像动画一样

https://pub.dev/packages/spring_button 例子;

SpringButton(
          SpringButtonType.OnlyScale,
          row(
            "Increment",
            Colors.deepPurpleAccent,
          ),
          onTapDown: (_) => incrementCounter(),
          onLongPress: () => timer = Timer.periodic(
            const Duration(milliseconds: 100),
            (_) => incrementCounter(),
          ),
          onLongPressEnd: (_) {
            timer?.cancel();
          },
        ),
      ),

我发现我的代码有问题,动画被“颠倒”了,onTapDown 会导致 child 展开(没有任何反应,因为 child 已经达到最大比例),所以我只是反转 _controllerA.reverse_controllerA.forward(实际上用 _controllerA.fling 替换了 _controllerA.forward)。 这是最终代码:

class OnTapScaleAndFade extends StatefulWidget {
  final Widget child;
  final void Function() onTap;
  const OnTapScaleAndFade({Key key, this.child, this.onTap}) : super(key: key);

  @override
  _OnTapScaleAndFadeState createState() => _OnTapScaleAndFadeState();
}

class _OnTapScaleAndFadeState extends State<OnTapScaleAndFade>
    with TickerProviderStateMixin {
  double squareScaleA = 1;
  AnimationController _controllerA;
  @override
  void initState() {
    _controllerA = AnimationController(
      vsync: this,
      lowerBound: 0.98,
      upperBound: 1.0,
      value: 1,
      duration: Duration(milliseconds: 10),
    );
    _controllerA.addListener(() {
      setState(() {
        squareScaleA = _controllerA.value;
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.translucent,
      onTap: () {
        _controllerA.reverse();
        widget.onTap();
      },
      onTapDown: (dp) {
        _controllerA.reverse();
      },
      onTapUp: (dp) {
        Timer(Duration(milliseconds: 150), () {
          _controllerA.fling();
        });
      },
      onTapCancel: () {
        _controllerA.fling();
      },
      child: Transform.scale(
        scale: squareScaleA,
        child: widget.child,
      ),
    );
  }

  @override
  void dispose() {
    _controllerA.dispose();
    super.dispose();
  }
}

随意添加自定义手势回调,我只需要 onTap。