监听Animation flutter内部的位置变化

问题描述 投票:0回答:1

当动画当前运行时(未完成或取消),是否可以监听子部件位置的变化? 例如 我们有这个变量:

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 时,它会根据目标小部件的位置确认我要执行某些操作。

flutter dart animation position listener
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;
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.