Zuckerbrenner
Zuckerbrenner

Reputation: 335

Flutter: How to terminate animation loop after x cycles?

Just started to learn Flutter. Trying to create an animated circle that expands and retracts x number of times and then terminates. How do I accomplish this?

Currently, my circle animation is expanding and then retracting in endless loop. Any guidance is appreciated.

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

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

class _BreathingCircleState extends State<BreathingCircle>
    with SingleTickerProviderStateMixin {
  late final AnimationController _controller;
  late final Animation<double?> _shapeSizeChanger;

  // **** Currently this animation runs in endless loop. How can I get it to stop after
  // x expansion-retraction cycles?
  @override
  void initState() {
    super.initState();
    _controller =
        AnimationController(duration: const Duration(seconds: 2), vsync: this)
          ..repeat(reverse: true);
    _shapeSizeChanger = Tween<double>(begin: 0, end: 300).animate(_controller)
      ..addListener(() {
        setState(() {});
      });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: const AnimationBreather(), //Stack of shapes
      width: _shapeSizeChanger.value,
      height: _shapeSizeChanger.value,
    );
  }

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

Upvotes: 0

Views: 1680

Answers (1)

WSBT
WSBT

Reputation: 36333

You are using a repeating AnimationController with a duration of 2 seconds. You started the animation with a loop: _controller.repeat(reverse: true). To stop it, you can call _controller.stop() or _controller.reset(). The only problem is, when to do it.

There are a couple of different approaches. The most obvious one is to use a Timer (or Future.delayed) to schedule a callback a few seconds later. For example, your animation runs for 2 seconds and reverses for another 2 seconds, that's 4 seconds in total. To stop after 10 repeats, is the same as saying "stop after 40 seconds", so you can write:

Future.delayed(Duration(seconds: 40), () {
  _controller.stop();
});

Alternatively, you can use addStatusListener to monitor your animation progress. Perhaps instead of running your animation in a loop, you can make your animation run only once. And then once you monitored it had finished running and stopped, you can start it again, so you can keep track of how many times it has started.

Upvotes: 2

Related Questions