flutterfadein

Fade in / out animation is not working: state is not an argument


I am trying to apply Fade Transition to the image on the screen, but facing error which says that state that I am using is not an argument.

I was following the official tutorial: https://www.youtube.com/watch?v=rLwWVbv3xDQ

Source:

class _MyFadeInState extends State<MyFadeIn>
    with SingleTickerProviderStateMixin {
  // ignore: inference_failure_on_function_return_type
  MyFadeIn({@required this.child});

  late AnimationController _controller;
  late Animation _animation;

  @override
  void initState() {
    _controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 2),
    );
    _animation = Tween(
      begin: 0.0,
      end: 1.0,
    ).animate(_controller);
  }

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

  @override
  Widget build(BuildContext, context) {
    _controller.forward();
    createState() => _MyFadeInState();
    final controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 2),
    );
    final animation = Tween(
      begin: 0.0,
      end: 1.0,
    ).animate(controller);
    controller.forward();
    return FadeTransition(opacity: _animation, child: widget.child);
  }
}

Solution

  • Here's an implementation that fades in whatever child widget you pass into MyFadeIn (see comments):

    /// Stateful widgets are composed of two classes: [StatefulWidget] and [State].
    ///
    /// The [StatefulWidget] creates its state object in the [createState] method.
    ///
    /// [MyFadeIn] <<<<<<<<<<<< This is the stateful widget.
    /// [_MyFadeInState] <<<<<< This is the associated state object type.
    class MyFadeIn extends StatefulWidget {
      const MyFadeIn({super.key, required this.child});
    
      final Widget child;
    
      /// Note that there isn't a [build] method here. Only a [createState] method.
      @override
      State<MyFadeIn> createState() => _MyFadeInState();
    }
    
    class _MyFadeInState extends State<MyFadeIn> with TickerProviderStateMixin {
      /// We will mark this as 'final', because once initialized in 'initState', it
      /// will never change.
      late final AnimationController _controller;
    
      /// Specify a type for the generic type argument of Animation<T>.
      ///
      /// In this case, since we're animating from 0.0 to 1.0, it is 'double'.
      ///
      /// Marked as final; see above.
      late final Animation<double> _animation;
    
      @override
      void initState() {
        super.initState();
    
        _controller = AnimationController(
          vsync: this,
          duration: const Duration(seconds: 2),
        );
    
        _animation = Tween(
          begin: 0.0,
          end: 1.0,
        ).animate(_controller);
      }
    
      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      /// The state object is the one that overrides the [build] method.
      @override
      Widget build(BuildContext context) {
        _controller.forward();
    
        /// 1. This is not necessary, because we will use '_controller' instead.
        ///
        /// Notes:
        /// Additionally, instantiating a second 'AnimationController' will cause
        /// an exception because this class uses a 'SingleTickerProviderStateMixin'.
        ///
        /// A 'SingleTickerProviderStateMixin' is a 'TickerProviderStateMixin' that
        /// only supports a single ticker; think of this as only supporting a single
        /// AnimationController.
    
        // final controller = AnimationController(
        //   vsync: this,
        //   duration: const Duration(seconds: 2),
        // );
    
        /// 2. This is not necessary, because we will use '_animation' instead.
    
        // final animation = Tween(
        //   begin: 0.0,
        //   end: 1.0,
        // ).animate(controller);
    
        return FadeTransition(opacity: _animation, child: widget.child);
      }
    }
    

    Usage:

    MyFadeIn(child: Container(color: Colors.pink))
    ///             ^^^^^ Replace with your image.
    

    I see a bit of a misunderstanding on widgets, so I recommend studying the following: https://docs.flutter.dev/ui/widgets-intro