image

18 Mar 2026

9K

35K

Flutter Fade & Scale Animations for Alert Dialogs

Alert dialogs are crucial components in modern applications, providing users with important information or requiring their immediate attention. While standard dialogs are functional, adding subtle animations can significantly enhance the user experience, making interactions feel more fluid and engaging. This article explores how to implement appealing fade and scale animations for Flutter's AlertDialog using its powerful transitionBuilder property.

Why Fade and Scale?

Fade and scale are two of the most popular and effective animation types for UI elements, especially dialogs. A fade animation smoothly reveals or conceals an element by gradually changing its opacity. A scale animation makes an element appear to grow into place or shrink away. When combined, they create a dynamic, professional, and intuitive effect that makes dialogs feel integrated rather than abruptly popping onto the screen.

Basic Alert Dialog in Flutter

Before diving into animations, let's recall how to display a standard AlertDialog in Flutter:


Future<void> _showBasicAlertDialog(BuildContext context) async {
  return showDialog<void>(
    context: context,
    builder: (BuildContext context) {
      return AlertDialog(
        title: const Text('Basic Alert'),
        content: const SingleChildScrollView(
          child: ListBody(
            children: <Widget>[
              Text('This is a basic alert dialog without animations.'),
              Text('You can add more content here.'),
            ],
          ),
        ),
        actions: <Widget>[
          TextButton(
            child: const Text('Approve'),
            onPressed: () {
              Navigator.of(context).pop();
            },
          ),
          TextButton(
            child: const Text('Cancel'),
            onPressed: () {
              Navigator.of(context).pop();
            },
          ),
        ],
      );
    },
  );
}

Customizing Dialog Transitions with transitionBuilder

The magic for custom dialog animations in Flutter lies within the showDialog function's transitionBuilder parameter. This parameter accepts a TransitionBuilder callback, which provides access to the primary animation, secondary animation, and the child widget (your AlertDialog).

The signature of transitionBuilder is:


Widget Function(
  BuildContext context,
  Animation<double> animation,
  Animation<double> secondaryAnimation,
  Widget child,
)
  • context: The build context.
  • animation: The primary animation for the dialog's entry. This is the one we'll primarily use.
  • secondaryAnimation: The animation for other elements (e.g., dismissing the previous route). Less commonly used for simple dialog entry/exit.
  • child: Your AlertDialog widget.

Implementing the Fade Animation

To add a fade animation, we'll wrap the child (our AlertDialog) with a FadeTransition widget. The FadeTransition takes an opacity property, which should be an Animation<double>. We can directly pass the animation object provided by the transitionBuilder.


// Inside showDialog
transitionBuilder: (context, animation, secondaryAnimation, child) {
  return FadeTransition(
    opacity: animation, // Uses the primary animation for opacity
    child: child, // Your AlertDialog
  );
},

Implementing the Scale Animation

Similarly, for a scale animation, we use the ScaleTransition widget. It requires a scale property, which is also an Animation<double>. Again, the primary animation from the builder can be used.


// Inside showDialog
transitionBuilder: (context, animation, secondaryAnimation, child) {
  return ScaleTransition(
    scale: animation, // Uses the primary animation for scale
    child: child, // Your AlertDialog
  );
},

Combining Fade and Scale for a Dynamic Effect

To achieve both fade and scale effects, we can simply nest the two transition widgets. The order usually doesn't matter significantly for these two, but commonly ScaleTransition is outside FadeTransition, or vice versa. Let's place ScaleTransition outside for this example.


// Inside showDialog
transitionBuilder: (context, animation, secondaryAnimation, child) {
  return ScaleTransition(
    scale: animation, // Scale from 0 to 1
    child: FadeTransition(
      opacity: animation, // Fade from 0 to 1
      child: child, // Your AlertDialog
    ),
  );
},

This creates an effect where the dialog simultaneously fades in and scales up from a small point to its full size.

Full Example: Animated Alert Dialog

Here's a complete example demonstrating how to integrate the combined fade and scale animation into an AlertDialog. We'll use a simple button to trigger the dialog.


import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Animated Dialog Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({super.key});

  Future<void> _showAnimatedAlertDialog(BuildContext context) async {
    return showDialog<void>(
      context: context,
      barrierDismissible: true, // Allow dismissing by tapping outside
      transitionDuration: const Duration(milliseconds: 300), // Duration for the animation
      transitionBuilder: (context, animation, secondaryAnimation, child) {
        // Use a curved animation for a smoother effect
        final curvedAnimation = CurvedAnimation(
          parent: animation,
          curve: Curves.easeOutBack, // Example curve
        );

        return ScaleTransition(
          scale: curvedAnimation, // Apply scale transition with curve
          child: FadeTransition(
            opacity: animation, // Apply fade transition (can also use curvedAnimation)
            child: child, // The actual AlertDialog
          ),
        );
      },
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('Animated Alert!'),
          content: const SingleChildScrollView(
            child: ListBody(
              children: <Widget>[
                Text('This dialog uses a delightful fade and scale animation.'),
                Text('Enjoy the smooth transition!'),
              ],
            ),
          ),
          actions: <Widget>[
            TextButton(
              child: const Text('Awesome'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
            TextButton(
              child: const Text('Dismiss'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Animated Dialog Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () => _showAnimatedAlertDialog(context),
          child: const Text('Show Animated Dialog'),
        ),
      ),
    );
  }
}

Dissecting the Animation Components

  • animation (Animation<double>): This is the primary animation object provided by showDialog. It typically animates from 0.0 to 1.0 over the transitionDuration.
  • transitionDuration: A property of showDialog that controls how long the transition animation plays. A duration between 200 and 500 milliseconds is often a good starting point.
  • CurvedAnimation: While the raw animation provides a linear progression, CurvedAnimation allows you to apply non-linear curves to the animation. For instance, Curves.easeOutBack makes the dialog slightly "overshoot" its final size before settling, creating a bouncy, pleasing effect. You wrap the primary animation with a CurvedAnimation:
    
    final curvedAnimation = CurvedAnimation(
      parent: animation,
      curve: Curves.easeOutBack,
    );
    
    Then, you pass curvedAnimation to the scale property of ScaleTransition.

Best Practices for Dialog Animations

  • Keep it Swift: Animations should enhance, not hinder. A duration of 200-500ms is usually ideal. Longer durations can feel sluggish.
  • Choose Appropriate Curves: Experiment with different Curves from flutter/animation.dart. Curves.easeOut, Curves.decelerate, Curves.bounceOut, or Curves.elasticOut can add personality.
  • Be Consistent: If you animate one dialog, consider animating others similarly for a consistent user experience.
  • Test on Different Devices: Animation performance can vary. Test your animations on lower-end devices to ensure smoothness.
  • Accessibility: While animations are great, ensure they don't cause discomfort for users sensitive to motion. Flutter's framework often respects system-wide "reduce motion" settings, but be mindful of overly aggressive animations.

Conclusion

Integrating fade and scale animations into your Flutter AlertDialogs is a straightforward process that yields significant improvements in user experience. By leveraging the transitionBuilder and combining simple FadeTransition and ScaleTransition widgets, you can transform static dialogs into engaging, dynamic elements. Remember to experiment with durations and animation curves to find the perfect balance that aligns with your application's aesthetic and user flow.

Related Articles

May 14, 2026

Building a Multi-Event Countdown Timer Widget with Reminders, Notifications, Repeat, and Custom Labels in Flutter

Building a Multi-Event Countdown Timer Widget with Reminders, Notifications, Repeat, and Custom Labels in Flutter Countdown timers are essential in many applic

May 11, 2026

Unleashing Dynamic UIs: Flutter's Animation Prowess

Unleashing Dynamic UIs: Flutter's Animation Prowess for Slide & Scale Effects Flutter's declarative UI framework, combined with its powerful animation capabilit

May 11, 2026

Building a Product Detail Page Widget in Flutter with Related Items, Review Carousel, Promo Badges, and Quick Buy

Building a Product Detail Page Widget in Flutter with Related Items, Review Carousel, Promo Badges, and Quick Buy A well-designed Product Detail Page (PDP) is