Jaafar Melhem
Jaafar Melhem

Reputation: 400

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.

Upvotes: 3

Views: 1418

Answers (1)

can
can

Reputation: 444

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

Upvotes: 4

Related Questions