February 6, 2026

Flutter Splash Screen Animation Explained

This article explains how to build a production style splash screen animation in Flutter. Using a Swiggy inspired design, I cover animation controllers, tweens, intervals, text animations, Hero transitions, and navigation making Flutter animations easier to understand for beginners.

Posted by
L
Likitha N@likithan

In this post, I will explain how to build a production style splash screen animation in Flutter.

Spliting of Animation

Splitting Screen

  1. The Scaling of the glass container (big → normal)
  2. The icon fade in (delayed)
  3. The text fade + slide in (delayed)
  4. Transition to Home Screen (with Hero)

Designing the splash screen UI first

  • Before animating anything, I built a static UI.

Swiggy Splash Screen

AnimationController: the timeline manager

late AnimationController controller;

controller = AnimationController(
  vsync: this,
  duration: Duration(seconds: 1),
);

Think of the controller as: A timeline that moves from 0 → 1

  • All animations are mapped onto this timeline.

Scaling the glass container (big → normal)

  • The first animation was scaling the glass container.
scaleAnimation = Tween<double>(
  begin: 5.0,
  end: 1.0,
).animate(
  CurvedAnimation(
    parent: controller,
    curve: Curves.easeInOut,
  ),
);
  • At time 0 → scale is 5.0
  • At time 1 → scale is 1.0
  • The Tween does value mapping, not timing.

Why Transform.scale is used

Transform.scale(
  scale: scaleAnimation.value,
  child: ...
)
  • Transform changes how a widget is drawn, not how it is laid out. This is important because:
  • Layout doesn’t break
  • No overflow issues
  • Smooth GPU-friendly animation

Using AnimatedBuilder (and why it matters)

Instead of calling setState() on every frame, I used:

AnimatedBuilder(
  animation: controller,
  builder: (context, _) {
    return Transform.scale(...);
  },
);

AnimatedBuilder is more efficient than setState because:

  • It only rebuilds the specific widget being animated.
  • It avoids unnecessary rebuilds of the entire widget tree.

Delaying the icon appearance using Interval

  • The icon should not appear immediately.
  • So I used Interval to delay its opacity animation.
opacityAnimation = Tween<double>(
  begin: 0.0,
  end: 1.0,
).animate(
  CurvedAnimation(
    parent: controller,
    curve: Interval(0.9, 1.0, curve: Curves.easeOut),
  ),
);
  • Icon opacity starts animating at 90% of the timeline
  • Before that, it stays invisible Interval slices the timeline, not the value.

Animating text (fade + slide, not scale)

textOpacity = Tween<double>(0.0, 1.0).animate(
  CurvedAnimation(
    parent: controller,
    curve: Interval(0.85, 1.0),
  ),
);

textSlide = Tween<double>(12.0, 0.0).animate(
  CurvedAnimation(
    parent: controller,
    curve: Interval(0.85, 1.0),
  ),
);
  • And applied it using:
Transform.translate(
  offset: Offset(0, textSlide.value),
  child: Opacity(
    opacity: textOpacity.value,
    child: ...
  ),
);

Transitioning to Home Screen (correct way)

  • Instead of using Future.delayed, I listened to animation status:
controller.addStatusListener((status) {
  if (status == AnimationStatus.completed) {
    Navigator.pushReplacement(
      context,
      PageRouteBuilder(
        pageBuilder: (_, _, _) => HomeScreen(),
      ),
    );
  }
});

This approach is more reliable than using Future.delayed because it ensures the transition happens only after the animation is fully completed.

Shared element transition using Hero

The home icon moves from Splash → AppBar using Hero.

Hero(
  tag: 'hero',
  child: Icon(...)
)

Making the Hero movement curved (premium feel)

  • By default, Hero moves linearly. To add a natural curve, I used:
createRectTween: (begin, end) {
  return MaterialRectArcTween(begin: begin, end: end);
},

This follows Material Design motion rules and feels much smoother.

Enjoyed this article?

Share it with your friends and help others learn too!

Flutter Splash Screen Animation Explained | AppykitUI