Search code examples
flutterflutter-animation

How to chain the SlideTransition


enter image description here

I use animation making my widget move.

when I click play button, I want the widget

  1. move from 1 to 2
  2. waiting for few seconds
  3. move from 2 to 3 and disappear

Now I just complete 1 and have no idea how to achieve 2 and 3

Here is my code in State.

  @override
  void initState() {
    animationController = AnimationController(duration: widget.duration, vsync: this);
    animation = Tween(
        begin: const Offset(1.0, 0),
        end: const Offset(0.0, 0)
    ).animate(animationController);
    animationController.forward();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {

      },
      child: SlideTransition(
        position: animation,
        child: getBarrageWidget(),//can be any widget, not important.
      ),
    );
  }

Any help will be appreciate.


Solution

  • There is no animator set in flutter so you will have to manage the animation yourself.

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return OrientationBuilder(
          builder: (context, orientation) {
            return const MaterialApp(
              title: 'Demo',
              debugShowCheckedModeBanner: false,
              home: MyHomePage(),
            );
          },
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({super.key});
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
      late AnimationController _animationController;
      late AnimationController _animationController2;
      late AnimationController _animationController3;
      late Animation<Offset> _animation;
      late Animation<Offset> _animation2;
      late Animation<Offset> _animation3;
      late Animation<Offset> _animation4;
      late Animation<double> _fadeAnimation;
    
      bool isFirstAnimationCompleted = false;
      bool isSecondAnimationCompleted = false;
    
      bool isAnimating = false;
      @override
      void initState() {
        super.initState();
        _animationController = AnimationController(
          vsync: this,
          duration: const Duration(seconds: 3),
        );
    
        _animationController = AnimationController(
          vsync: this,
          duration: const Duration(seconds: 3),
        );
    
        _animationController.addStatusListener((status) {
          if (status == AnimationStatus.completed) {
            Future.delayed(const Duration(seconds: 3), () {
              _animationController2.forward();
            });
            isFirstAnimationCompleted = true;
            setState(() {});
          }
        });
    
        _animationController2 = AnimationController(
          vsync: this,
          duration: const Duration(milliseconds: 1500),
        );
    
        _animationController2.addStatusListener((status) {
          if (status == AnimationStatus.completed) {
            isSecondAnimationCompleted = true;
            Future.delayed(const Duration(milliseconds: 500), () {
              setState(() {});
              _animationController3.forward();
            });
          }
        });
    
        _animation = Tween(begin: const Offset(-1.0, 0), end: const Offset(1.0, 0))
            .animate(_animationController);
        _animation2 = Tween(begin: const Offset(-2.0, 0), end: const Offset(0.0, 0))
            .animate(_animationController);
    
        _animation3 = Tween(begin: const Offset(0.0, 0), end: const Offset(1.0, 0))
            .animate(_animationController2);
        _animation4 = Tween(begin: const Offset(-1.0, 0), end: const Offset(0.0, 0))
            .animate(_animationController2);
    
        _animationController3 = AnimationController(
          vsync: this,
          duration: const Duration(milliseconds: 500),
        );
    
        _fadeAnimation =
            Tween<double>(begin: 1.0, end: 0.0).animate(_animationController3);
      }
    
      @override
      void dispose() {
        _animationController.dispose();
        _animationController2.dispose();
        _animationController3.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        final child = Stack(
          children: [
            SlideTransition(
              position: _animation,
              child: Container(
                color: Colors.green,
                width: double.infinity,
                height: 400,
                child: const Center(
                  child: Text(
                    'Hello World',
                    style: TextStyle(fontSize: 42),
                  ),
                ),
              ),
            ),
            SlideTransition(
              position: !isFirstAnimationCompleted ? _animation2 : _animation3,
              child: Container(
                color: Colors.orange,
                width: double.infinity,
                height: 400,
                child: const Center(
                  child: Text(
                    'Hello World Again',
                    style: TextStyle(fontSize: 42),
                  ),
                ),
              ),
            ),
            if (isFirstAnimationCompleted)
              SlideTransition(
                position: _animation4,
                child: Container(
                  color: Colors.red,
                  width: double.infinity,
                  height: 400,
                  child: const Center(
                    child: Text(
                      'Hello World Third Time',
                      style: TextStyle(fontSize: 42),
                    ),
                  ),
                ),
              ),
          ],
        );
        return Scaffold(
          appBar: AppBar(),
          body: isFirstAnimationCompleted && isSecondAnimationCompleted
              ? FadeTransition(
                  opacity: _fadeAnimation,
                  child: child,
                )
              : child,
          floatingActionButton: FloatingActionButton(
            onPressed: _animationController.forward,
            child: const Icon(
              Icons.play_arrow,
            ),
          ),
        );
      }
    }