Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

listen for the position changes inside Animation flutter

Is there away to listen for the changes of the child widget positions when the animation currently running (not completed or canceled)? for example we have this variables:

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

I need to listen for the position of the target widget inside this 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,
    )
  ],)
  ),
)

when the height of the AnimatedContainer reach 70 for example, it confirm me based on the position of the target widget to do some thing.

like image 941
Jaafar Melhem Avatar asked Jan 26 '26 13:01

Jaafar Melhem


1 Answers

Your exact requirement is unclear. Depending on what you mean by 'do something to a target widget' you might need to choose a different method. However, if you'd like to add a listener to an animation or react to the current animation value you are better off with an AnimatedBuilder. I'm including a basic example that could help with your case.

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

like image 143
can Avatar answered Jan 28 '26 05:01

can