I am building a language app, when the student is learning a new word, each syllable in the new word will be repeated three times. I have three progress bars to indicate to the student how long they have to wait until the next repetition.

Each progress bar has a duration of 3 seconds. When the first progress bar completes, it should trigger the second progress bar, when the second finishes it should trigger the third progress bar.

When the third bar completes, it should reset all of the progress bars and restart the process all over again.

The key here is to sequence the animation of each progress bar so that they can call a function on complete. This is the beginning of my problem.

I don't know how to get the progress bars to animate in sequence and to call a function when they are complete.

How do I go about achieving this with flutter? I already built this app with KivyMD but now I have to rebuild it with Flutter. However, KivyMD animations are simple but Flutter animations are complicated.

import 'package:blog/screens/widgets/nav_menu.dart';
import 'package:flutter/material.dart';

class AnimationTest3 extends StatefulWidget {
  const AnimationTest3({Key? key}) : super(key: key);

  @override
  _AnimationTest3State createState() => _AnimationTest3State();
}

class _AnimationTest3State extends State<AnimationTest3>
    with TickerProviderStateMixin {
  late AnimationController _controller;
  double progress1 = 0;
  double progress2 = 0;
  double progress3 = 0;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this);
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: Drawer(child: NavMenu()),
      appBar: AppBar(title: Text("Animation Test 3"), elevation: 0),
      body: LayoutBuilder(
        builder: (context, constraints) {
          return Column(children: [
            Container(
                height: constraints.maxHeight * 0.3, color: Colors.indigo[50]),
            Container(height: constraints.maxHeight * 0.4, color: Colors.white),
            Container(
              height: constraints.maxHeight * 0.3,
              color: Colors.indigo[50],
              child: LayoutBuilder(
                builder: (context, constraints) {
                  return Row(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      // PROGRESS BAR #1
                      Container(
                        padding: EdgeInsets.symmetric(horizontal: 2.0),
                        height: 4,
                        width: constraints.maxWidth * 1 / 3,
                        child: LinearProgressIndicator(value: progress1),
                      ),
                      Container(
                        // PROGRESS BAR #2
                        padding: EdgeInsets.symmetric(horizontal: 2.0),
                        height: 4,
                        width: constraints.maxWidth * 1 / 3,
                        child: LinearProgressIndicator(value: progress2),
                      ),
                      Container(
                        // PROGRESS BAR #3
                        padding: EdgeInsets.symmetric(horizontal: 2.0),
                        height: 4,
                        width: constraints.maxWidth * 1 / 3,
                        child: LinearProgressIndicator(value: progress3),
                      ),
                    ],
                  );
                },
              ),
            )
          ]);
        },
      ),
    );
  }
}


Solution 1: Jim

look into this reference for staggered animation, staggered animation, your situation should be:

controller = AnimationController(
        duration: const Duration(milliseconds: 9000), vsync: this);

        progress1 = Tween<double>(
          begin: 0.0,
          end: 0.3,
        ).animate(
          CurvedAnimation(
            parent: controller,
            curve: const Interval(
              0.0,
              0.33,
              curve: Curves.ease,
            ),
          ),
        ),

        progress2 = Tween<double>(
          begin: 0.0,
          end: 0.3,
        ).animate(
          CurvedAnimation(
            parent: controller,
            curve: const Interval(
              0.33,
              0.66,
              curve: Curves.ease,
            ),
          ),
        ),

        progress3 = Tween<double>(
          begin: 0.0,
          end: 0.3,
        ).animate(
          CurvedAnimation(
            parent: controller,
            curve: const Interval(
              0.66,
              1.0,
              curve: Curves.ease,
            ),
          ),
        ),