Multiple Flutter animation not working one after the other

Issue

I am new to flutter, at the moment I am trying to make a simple app where when the APP is opened a Text appears with fadeIn and changes its position from bottom to top. Yes, there are two animations which I want to Transit. The first one is FadeIn after it is completed goes and carries on with the next animation which is Position Transition which changes the Vertical position of the Text from 400.0 to 200.0 pixels.

I was able to achieve the fadeIn process but position one is not being applied.
First I want the FadeIn TextAnimation to start after it’s done I want to start the PositionAnimation, not at the same time but one after the other when the animations complete.

Here is the code:

class _SplashScreenState extends State<SplashScreen>
 with TickerProviderStateMixin {
 AnimationController animationController;
 double position = 400.0;
 Animation<double> _animation;
 Tween<double> tween;

  @override
    void initState() {
    super.initState();

    animationController = AnimationController(
    vsync: this,
    duration: Duration(milliseconds: 700),
  );

   _animation = CurvedAnimation(
   parent: animationController,
   curve: Curves.easeIn,
 );

   tween = Tween(begin: 400, end: 200);

   animationController.forward();
}

 @override
  Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.amber,
    body: FadeTransition(
      opacity: _animation,

      child: Padding(
        padding: EdgeInsets.symmetric(
            vertical:_animation.isCompleted? tween : position,
            horizontal: 180.0),
        child: Text(
          'My Life',
          style: TextStyle(
              fontWeight: FontWeight.bold,
              fontSize: 30.0,
              color: Colors.white70,
              letterSpacing: 2.0),
        ),
      ),
    ),
  );
}

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

Any expertise, Since I am new I am not sure what I did wrong. Please guide me, anyone.

Here is the updated code which I have tried today but still I am not getting the result:

class _SplashScreenState extends State<SplashScreen>
  with TickerProviderStateMixin {
AnimationController animationControllerFade;
AnimationController animationControllerPost;
double position = 400.0;
FadeTransition fadeTransition;
Animation<double> animation;
int i = 0;

@override
void initState() {
   super.initState();

   animationControllerFade = AnimationController(
      vsync: this,
    duration: Duration(milliseconds: 700),
   );
   animationControllerPost = AnimationController(
     vsync: this,
   duration: Duration(milliseconds: 700),
   );

   animation = CurvedAnimation(
     parent: animationControllerFade,
     curve: Curves.easeIn,
   );

   animationControllerFade.forward();
 }

 @override
 Widget build(BuildContext context) {
   Scaffold sc;
   sc = Scaffold(
     backgroundColor: Colors.amber,
   );

   fadeTransition = FadeTransition(
     opacity: animation,
     child: paddingOwn(position),
   );

   animationControllerFade.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
       animationControllerPost.forward();
       sc = Scaffold(
          body: TweenAnimationBuilder(
          curve: Curves.easeIn,
          duration: Duration(milliseconds: 700),
          tween: Tween<double>(begin: 400.0, end: 200.0),
          builder: (BuildContext context, double val, Widget child) {
            return Positioned(child: paddingOwn(val));
           },
          ),
        );
       } 
       else {
          sc = Scaffold(body: fadeTransition);
       }
     });

     return sc;
   }

   Widget paddingOwn(double val) {
      return Padding(
        padding: EdgeInsets.symmetric(
        vertical: val,
        horizontal: 180,
      ),
      child: Text(
        'My Life',
        style: TextStyle(
           fontWeight: FontWeight.bold,
           fontSize: 30.0,
           color: Colors.white70,
           letterSpacing: 2.0),
      ),
     );
    }

    @override
    void dispose() {
      animationControllerFade.dispose();
      animationControllerPost.dispose();
      super.dispose();
    }
   }

still not result.

Solution

If you want to get the position transition, you need to use SlideTransition.

Also, you need to animate the Tween in order to get the values interpolated properly.

I changed a little your code in order to center the text and animate it from there. Anyway, just keep in mind that SlideTransition works with Offsets in a relative way from the size of the child

Now, you should be able to adapt this code to the final result you want to achieve:

class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMixin {
  AnimationController _fadeAnimationController;
  AnimationController _slideAnimationController;
  double position = 400.0;
  Animation<double> _fadeAnimation;
  Animation<Offset> _slideAnimation;

  @override
  void initState() {
    super.initState();

    _fadeAnimationController = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 700),
    );

    _slideAnimationController = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 700),
    );

    _fadeAnimation = CurvedAnimation(
      parent: _fadeAnimationController,
      curve: Curves.easeIn,
    );

    _slideAnimation = Tween(begin: Offset(0, 0), end: Offset(0, -3)).animate(CurvedAnimation(
      parent: _slideAnimationController,
      curve: Curves.easeInOut,
    ));

    _play();
  }

  Future<void> _play() async {
    try {
      await _fadeAnimationController.forward().orCancel;
      await _slideAnimationController.forward().orCancel;
    } on TickerCanceled {
      //Handle if animation was canceled for whatever reason if you need it
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.amber,
      body: Center(
        child: SlideTransition(
          position: _slideAnimation,
          child: FadeTransition(
            opacity: _fadeAnimation,
            child: Text(
              'My Life',
              style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30.0, color: Colors.white70, letterSpacing: 2.0),
            ),
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    _fadeAnimationController.dispose();
    _slideAnimationController.dispose();
    super.dispose();
  }
}

Update:

You are not seeing changes with your padding because you have two mistakes:

  • You are not animating the tween
  • You are using symmetric, that adds the same margin from both sides.

To solve the tween thing, you need to add something like this:

tween = Tween(begin: 400, end: 200).animate(animationController);

To solve the padding thing, you can use only, to apply the padding only in one side:

padding: EdgeInsets.only(top: tween)

Answered By – Mou

Answer Checked By – Clifford M. (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.