监听Flutter中动画的位置变化

3

有没有办法在动画正在运行时(未完成或取消)监听子小部件位置的变化? 例如,我们有以下变量:

GlobalKey globalKey= GlobalKey();
bool isAnimated =false;

我需要监听目标小部件在这个AnimatedContainer中的位置:

 InkWell(
  onTap:() => setState(() {isAnimated=!isAnimated};) ,

  child:   AnimatedContainer(
  duration: Duration(milliseconds: 1000),
  width: 200,
  height: isAnimated?100:40,
  child: Column(
 mainAxisAlignment: MainAxisAlignment.end,
children: [
  
    SizedBox(height: 10,),
  
    //the target widget
    SizedBox(
      key: globalKey,
    )
  ],)
  ),
)

当AnimatedContainer的高度达到70时,例如,根据目标小部件的位置,它会确认我执行某些操作。
1个回答

4

您的具体要求不清楚。根据您所说的“对目标组件做某事”的意思,您可能需要选择不同的方法。然而,如果您想要向动画添加监听器或者对当前动画值进行反应,最好使用AnimatedBuilder。我包含了一个基本示例,可能对您有帮助。

class MyAnimatedWidget extends StatefulWidget {
  const MyAnimatedWidget({
    Key? key,
  }) : super(key: key);

  @override
  State<MyAnimatedWidget> createState() => _MyAnimatedWidgetState();
}

class _MyAnimatedWidgetState extends State<MyAnimatedWidget>
    with TickerProviderStateMixin {
  late final AnimationController _controller;
  late Animation _animation;
  GlobalKey globalKey = GlobalKey();

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 1000),
    );
    _controller.addListener(() {
      //also possible to listen for changes with a listener
    });
    _animation = CurveTween(curve: Curves.easeOut).animate(_controller);
    _controller.forward();
  }

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

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
        animation: _animation,
        builder: (context, child) {
          return InkWell(
            onTap: () {},
            child: Container(
                width: 200,
                height: _containerHeightBuilder(_controller.value),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    const SizedBox(
                      height: 10,
                    ),
                    //the target widget
                    SizedBox(
                      //or do something here with the current animation value
                      key: globalKey,
                    )
                  ],
                )),
          );
        });
  }

  double _containerHeightBuilder(double animationValue) {
    const double containerAnimationTarget = 60;
    const double containerBaseHeight = 40;
    const double thresholdHeight = 70;

    double currentHeight =
        containerBaseHeight + (containerAnimationTarget * animationValue);

    if (currentHeight == thresholdHeight) {
      //do something here
    }
    return currentHeight;
  }
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接