Flutter is really good at making animations between two distinct values easy, but what would be the best way to go about animating a value that ends at the same place it started?

e.g I have a container that I want to contract and then expand back to its original width on user input.

Since it seems like there's no easy way to do this, I tried setting up an animation and animation controller and trying to call _controller.forward() and _controller.backword() in rapid succession (the beginning state is with the container fully expanded and the end state is with the container fully contracted). Note that I am trying to do this through the edge insets property.

Am I making this more complicated than it needs to be? Is there a better way?

void initState() {
super.initState();
_controller = AnimationController(
  vsync: this,
  duration: Duration(milliseconds: 1000),
);

_insetAnimation = Tween<EdgeInsetsGeometry>(
  begin: EdgeInsets.symmetric(horizontal: 0),
  end: EdgeInsets.symmetric(horizontal: 500),
).animate(
  CurvedAnimation(
    parent: _controller,
    curve: Curves.bounceIn,
  ),
);
_insetAnimation.addListener(() => setState(() {}));

}

...

FlatButton(
                onPressed: () {
                  setState(() {
                    isSignUp = !isSignUp;
                  _controller.forward();
                  });
                  Future.delayed(Duration(seconds: 1));
                  setState(() {
                    _controller.reverse();
                  });

Note that I am trying to achieve the desired result by expanding and contracting the edge insets. So far, I'm able to get it to contract when I just call forward, but when I add the reverse method right after it nothing happens. The delay in between was just a desperate attempt to make something out of nothing :)


Solution 1: Yechi

After some digging, I found out that I can use this syntax to get my desired effect with ..addStatusListener()

_insetAnimation = Tween<EdgeInsetsGeometry>(
  begin: EdgeInsets.symmetric(horizontal: 0),
  end: EdgeInsets.symmetric(horizontal: 25),
).animate(
  CurvedAnimation(
    parent: _controller,
    curve: Curves.easeOut,
    reverseCurve: Curves.bounceIn
  )..addStatusListener((status) {
      if (status == AnimationStatus.completed) {
       _controller.reverse();
      }
    }),
);
_insetAnimation.addListener(() => setState(() {}));

I'm still curious if there is a more efficient way to do this though