Animation in Flutter

Jumping Dots Animation in Flutter – Flutter Agency

Today we will learn how to create jumping dots animation in Flutter. The Facebook messenger uses jumping dots for message typing indication. Our final result will look like this.


We will start with basic steps.

  • Create Dot widget

Dot widget is a blue dot.

class DotWidget extends StatelessWidget {
  const DotWidget({
    Key? key,
  }) : super(key: key);
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(shape:, color: Colors.white),
      height: 10,
      width: 10,
  • Observe the Animation

In our jumping dots animation following events are happening

  1. You can see that each dot is going up and then coming back to its original position.
  2. When the previous dot is reaching its maximum top position current dot starts its movement.
  3. When the last dot reaches its original position the animation repeats itself.
  • Creating Animation

Here I will focus more on the logic of the animation.

Create JumpingDots stateful widget.

import 'package:flutter/material.dart';

class JumpingDots extends StatefulWidget {
  final int numberOfDots;

  const JumpingDots({Key? key, this.numberOfDots = 3}) : super(key: key);

  _JumpingDotsState createState() => _JumpingDotsState();

class _JumpingDotsState extends State
    with TickerProviderStateMixin {
  late List _animationControllers;

  List<animation> _animations = List();

  int animationDuration = 200;

  void initState() {

  void dispose() {
    for (var controller in _animationControllers) {

  Widget build(BuildContext context) {}


Use TickerProviderStateMixin in the state of the widget to perform the animation.

TickerProviderStateMixin : AnimationController requires a Ticker.A ticker is an object that calls a function at every frame. TickerProviderStateMixin is a helper that helps to manage the ticker.

We will have a List of AnimationController so that we can control the animation of each dot.

Similarly, we have a List of Animation to perform animation of each dot.

We will write the logic of our animation in the _initAnimation() method.

void _initAnimation() {
    ///initialization of _animationControllers
    ///each _animationController will have same animation duration
    _animationControllers = List.generate(
      (index) {
        return AnimationController(
            vsync: this, duration: Duration(milliseconds: animationDuration));

    ///initialization of _animations
    ///here end value is -20
    ///end value is amount of jump.
    ///and we want our dot to jump in upward direction
    for (int i = 0; i < widget.numberOfDots; i++) {
          Tween<double>(begin: 0, end: -20).animate(_animationControllers[i]));

    for (int i = 0; i < widget.numberOfDots; i++) {
      _animationControllers[i].addStatusListener((status) {
        //On Complete
        if (status == AnimationStatus.completed) {
          //return of original postion
          //if it is not last dot then start the animation of next dot.
          if (i != widget.numberOfDots - 1) {
            _animationControllers[i + 1].forward();
        //if last dot is back to its original postion then start animation of the first dot.
        // now this animation will be repeated infinitely
        if (i == widget.numberOfDots - 1 &&
            status == AnimationStatus.dismissed) {

    //trigger animtion of first dot to start the whole animation.

First, we created a List of AnimationController with the same duration.

Then we created a List of Animation with begin value 0 and end value -20.end value will the offset to which dot will jump and return.

After that, we have for loop which contains the main logic of the animation and it covers 3 points I explained above.

  1. Each AnimationController has a status listener. On Completion of the animation, we will perform the reverse operation.
  2. On Completion of the animation, the next dot will start the animation.
  3. On the return of the last dot, we will repeat the animation.

We have to trigger the animation manually for the first time after that animation will run infinitely.

  • Creating a build method
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Row(
          children: List.generate(widget.numberOfDots, (index) {
            //AnimatedBuilder widget will rebuild it self when
            //_animationControllers[index] value changes.
            return AnimatedBuilder(
              animation: _animationControllers[index],
              builder: (context, child) {
                return Container(
                  padding: EdgeInsets.all(2.5),
                  //Transform widget's translate constructor will help us to move the dot
                  //in upward direction by changing the offset of the dot.
                  //X-axis position of dot will not change.
                  //Only Y-axis position will change.
                  child: Transform.translate(
                    offset: Offset(0, _animations[index].value),
                    child: DotWidget(),

I have used AnimatedBuilder and Transform widget of flutter library to make the dot jump.

AnimatedBuilder: It rebuilds itself when provided animation changes its value.

Transform: It helps us to smoothly change its position.

That’s it!

This was all about jumping dots animation in Flutter.

If you have any doubts regarding this post please comment below.

Abhishek Dhanani

Written by Abhishek Dhanani

Abhishek Dhanani, a skilled software developer with 3+ years of experience, masters Dart, JavaScript, TypeScript, and frameworks like Flutter and NodeJS. Proficient in MySQL, Firebase, and cloud platforms AWS and GCP, he delivers innovative digital solutions.

Leave a comment

Your email address will not be published. Required fields are marked *

Discuss Your Project

Connect with Flutter Agency's proficient skilled team for your app development projects across different technologies. We'd love to hear from you! Fill out the form below to discuss your project.

Have Project For Us

Get in Touch

"*" indicates required fields

✓ Valid number ✕ Invalid number

ready to get started?

Fill out the form below and we will be in touch soon!

"*" indicates required fields

✓ Valid number ✕ Invalid number