Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter FadeIn/FadeOut animation together

in this simple sample code i want to have fadeIn and fadeOut animation together, but in this code fadeIn work only and reverse not work, how can i have both of them together?

import 'package:flutter/material.dart';

void main()=>runApp(MaterialApp(home: FadeTransitionSample(),));
class FadeTransitionSample extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _Fade();
}

class _Fade extends State<FadeTransitionSample> with TickerProviderStateMixin {
  AnimationController animation;
  Animation<double> _fadeInFadeOut;

  @override
  void initState() {
    super.initState();
    animation = AnimationController(vsync: this, duration: Duration(seconds: 3),);
    _fadeInFadeOut = Tween<double>(begin: 0.0, end: 0.1).animate(animation);

    animation.addListener((){
      if(animation.isCompleted){
        animation.reverse();
      }else{
        animation.forward();
      }
    });
    animation.repeat();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Center(
          child: FadeTransition(
            opacity: animation,
            child: Container(
              color: Colors.green,
              width: 100,
              height: 100,
            ),
          ),
        ),
      ),
    );
  }
}
like image 315
DolDurma Avatar asked Aug 18 '19 04:08

DolDurma


2 Answers

Alright, I am assuming, you are looking to get a FadeIn & FadeOut animation on your container.

There are a few things you need to change.

  1. The FadeTransition class should not take the animation for opacity, rather it should be the _fadeInFadeOut variable
  2. The animation starts, when you call the animation.forward() rather than animation.repeat() (Since in your case, you also need to reverse the animation, always start with the animation.forward() call).

Make sure to use the addStatusListener() method instead of addListener() since you get much better control over your states.

So, all of this put together, below is the working code to make your animation work.

import 'package:flutter/material.dart';

void main()=>runApp(MaterialApp(home: FadeTransitionSample(),));
class FadeTransitionSample extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _Fade();
}

class _Fade extends State<FadeTransitionSample> with TickerProviderStateMixin {
  AnimationController animation;
  Animation<double> _fadeInFadeOut;

  @override
  void initState() {
    super.initState();
    animation = AnimationController(vsync: this, duration: Duration(seconds: 3),);
    _fadeInFadeOut = Tween<double>(begin: 0.0, end: 0.5).animate(animation);

    animation.addStatusListener((status){
      if(status == AnimationStatus.completed){
        animation.reverse();
      }
      else if(status == AnimationStatus.dismissed){
        animation.forward();
      }
    });
    animation.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Center(
          child: FadeTransition(
            opacity: _fadeInFadeOut,
            child: Container(
              color: Colors.green,
              width: 100,
              height: 100,
            ),
          ),
        ),
      ),
    );
  }
}
like image 150
baradwaj Avatar answered Oct 19 '22 06:10

baradwaj


Option #1

Simple solution and straight forward with less code, the idea is to combine FadeOut inside FadeIn and give the FadeOut delay amount greater than the duration of the FadeIn, just copy and paste then just change the Image.asset widget to anything you want to fade in/out

1- Add this package.

2- Import it in your page import 'package:animate_do/animate_do.dart';

3- Add this Widget:

Widget _animateLogo() {
  return Container(
    child: FadeIn(
        animate: true,
        duration: Duration(seconds: 2),

        child: FadeOut(
          animate: true,
          delay: Duration(seconds: 2),
          duration: Duration(seconds: 1),

          // Just change the Image.asset widget to anything you want to fade in/out:
          child: Image.asset(
            "assets/images/logo.png",
            height: 150,
            width: 150,
            fit: BoxFit.contain,
          ), //Image.asset

        ) // FadeOut
    ),
  );
}

Option #2:

Use native class AnimatedOpacity class with setState:

// 1- Declare
bool _shouldFade = false;

// 2- Animation fucntion
Widget _animateLogo() {
  return AnimatedOpacity(
    duration: Duration(milliseconds: 200),
    opacity: _shouldFade ? 1 : 0,
    child: Container(
      // Whatever you want to fadein fadeout
    ),
  );
}

// 3- Animate whenever needed
setState(() {
  // Fade in
  _shouldFade = true;
});

// Fadeout after 3 seconds
Future.delayed(
  Duration(seconds: 3),
  () => setState(() {
        _shouldFade = false;
  }),
);
like image 2
Osama Remlawi Avatar answered Oct 19 '22 07:10

Osama Remlawi