blurred_overlay

A lightweight Flutter package to show beautiful blurred dialogs, modal bottom sheets, drawers, AppBars, and loading overlays with animations.

✨ Features

  • 🎯 Blur effect using BackdropFilter with customizable blur intensity
  • 🎨 Fully customizable design (colors, radius, padding, margins, shadows)
  • 📱 Drag-to-dismiss support with optional handle indicator
  • 🔧 Advanced parameters (maxHeight, enableDrag, useSafeArea, barrierColor)
  • ⚡ Optimized for both debug and release modes (no artifacts)
  • 🎭 Theme-aware with automatic color fallbacks
  • 📐 Smart layout system that adapts to content size
  • 🚀 Works with dialogs, bottom sheets, drawers, and frosted glass AppBars (docked & floating)

🖼️ Screenshots

bottom-sheet
Blurred BottomSheet
dialog
Blurred Dialog
blurred-drawer
Blurred Drawer
blurred appbar
Blurred AppBar
blurred nav bar
Blurred Navigation Bar
blurred-loading-overlay
Blurred Loading Overlay
blurred-progress-loading-overlay
Progress Loading Overlay

🚀 Quick Start

Installation

Add dependency into your pubspec.yaml

dependencies:
  blurred_overlay: latest

Then run

flutter pub get

Or use the command line

flutter pub add blurred_overlay

📱 Basic Usage

Blurred BottomSheet

showBlurredModalBottomSheet(
  context: context,
  showHandle: true,
  builder: (context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        const Padding(
          padding: EdgeInsets.symmetric(vertical: 8.0),
          child: Text(
            'System Information',
            style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
          ),
        ),
        const Divider(color: Colors.white24, indent: 20, endIndent: 20),
        const ListTile(
          dense: true,
          leading: Icon(Icons.devices, size: 20),
          title: Text('Device Name', style: TextStyle(fontSize: 14)),
          trailing: Text('Galaxy A50', style: TextStyle(fontSize: 12)),
        ),
        const ListTile(
          dense: true,
          leading: Icon(Icons.memory, size: 20),
          title: Text('RAM', style: TextStyle(fontSize: 14)),
          trailing: Text('12 GB', style: TextStyle(fontSize: 12)),
        ),
        const ListTile(
          dense: true,
          leading: Icon(Icons.sd_storage, size: 20),
          title: Text('ROM', style: TextStyle(fontSize: 14)),
          trailing: Text('256 GB', style: TextStyle(fontSize: 12)),
        ),
        const SizedBox(height: 10),
        const Center(
          child: Padding(
            padding: EdgeInsets.only(bottom: 10),
            child: Text(
              "Blurred BottomSheet",
              style: TextStyle(fontSize: 13, color: Colors.grey),
            ),
          ),
        ),
      ],
    );
  },
);

Blurred Dialog

showBlurredDialog(
      context: context,
      builder: (context) {
        return Dialog(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(16.0),
          ),
          child: Padding(
            padding: const EdgeInsets.all(24.0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                const Text(
                  'Root Status',
                  style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
                ),
                const SizedBox(height: 16.0),
                const Text(
                  'Your phone Galaxy A50 is not rooted.',
                  textAlign: TextAlign.left,
                  style: TextStyle(fontSize: 16.0),
                ),
                const SizedBox(height: 24.0),
                Align(
                  alignment: Alignment.bottomRight,
                  child: TextButton(
                    onPressed: () {
                      Navigator.of(context).pop(); // Close the dialog
                    },
                    child: const Text('CLOSE'),
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );

Blurred Drawer

Left Drawer:

Scaffold(
  drawer: BlurredDrawer(
    child: ListView(
      padding: EdgeInsets.zero,
      children: [
        DrawerHeader(
          decoration: BoxDecoration(
            color: Colors.blue.withValues(alpha: 0.3),
          ),
          child: const Text(
            'Menu',
            style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
          ),
        ),
        ListTile(
          leading: const Icon(Icons.home),
          title: const Text('Home'),
          onTap: () => Navigator.pop(context),
        ),
        ListTile(
          leading: const Icon(Icons.settings),
          title: const Text('Settings'),
          onTap: () => Navigator.pop(context),
        ),
      ],
    ),
  ),
  appBar: AppBar(title: const Text('App')),
  body: const Center(child: Text('Swipe from left')),
)

Right Drawer:

Scaffold(
  endDrawer: BlurredDrawer(
    position: DrawerPosition.right,
    child: ListView(
      padding: EdgeInsets.zero,
      children: [
        DrawerHeader(
          decoration: BoxDecoration(
            color: Colors.purple.withValues(alpha: 0.3),
          ),
          child: const Text(
            'Options',
            style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
          ),
        ),
        ListTile(
          leading: const Icon(Icons.notifications),
          title: const Text('Notifications'),
          onTap: () => Navigator.pop(context),
        ),
        ListTile(
          leading: const Icon(Icons.account_circle),
          title: const Text('Profile'),
          onTap: () => Navigator.pop(context),
        ),
      ],
    ),
  ),
  appBar: AppBar(title: const Text('App')),
  body: const Center(child: Text('Swipe from right')),
)

Blurred AppBar (GlassAppBar)

Frosted glass AppBar (also available via GlassAppBar alias) with customizable blur, borders, smooth scroll transitions, and support for docked or floating pill styles.

💡 Important: To enable background and scrolling content to pass and blur underneath the AppBar, set extendBodyBehindAppBar: true on your Scaffold.

1. Basic Docked Usage

Scaffold(
  extendBodyBehindAppBar: true,
  appBar: const BlurredAppBar(
    title: Text('Glass AppBar'),
    blurSigma: 10.0,
  ),
  body: ListView.builder(
    itemCount: 50,
    itemBuilder: (context, index) => ListTile(title: Text('Item $index')),
  ),
)

2. Scroll-Reactive Glass Effect (Dynamic Blur & Border)

Smoothly animates the blur intensity, background tint, and subtle bottom border when the user scrolls down:

class MyScrollPage extends StatefulWidget {
  const MyScrollPage({super.key});

  @override
  State<MyScrollPage> createState() => _MyScrollPageState();
}

class _MyScrollPageState extends State<MyScrollPage> {
  bool _isScrolled = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBodyBehindAppBar: true,
      appBar: BlurredAppBar(
        title: const Text('Dynamic Glass AppBar'),
        isScrolled: _isScrolled,
        blurSigma: 14.0,
        backgroundColor: Colors.white.withValues(alpha: 0.8),
        unScrolledBackgroundColor: Colors.white.withValues(alpha: 0.95),
        borderColor: Colors.blue.withValues(alpha: 0.2),
      ),
      body: NotificationListener<ScrollNotification>(
        onNotification: (notification) {
          final isScrolled = notification.metrics.pixels > 10;
          if (isScrolled != _isScrolled) {
            setState(() => _isScrolled = isScrolled);
          }
          return false;
        },
        child: ListView.builder(
          padding: EdgeInsets.only(
            top: MediaQuery.of(context).padding.top + kToolbarHeight + 12,
            bottom: 20,
          ),
          itemCount: 40,
          itemBuilder: (context, index) => ListTile(title: Text('Chat $index')),
        ),
      ),
    );
  }
}

3. Floating Pill / Island Glass Bar

Scaffold(
  extendBodyBehindAppBar: true,
  appBar: BlurredAppBar(
    title: const Text('Floating Glass Bar'),
    margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
    borderRadius: BorderRadius.circular(20.0),
    blurSigma: 15.0,
    actions: [
      IconButton(
        icon: const Icon(Icons.search),
        onPressed: () {},
      ),
    ],
  ),
  body: ListView(...),
)

4. Custom Styling & Parameters

Parameter Type Default Description
title Widget? null Primary title widget.
leading Widget? null Leading widget slot (e.g. back button / menu).
actions List<Widget>? null Action buttons displayed on the right.
blurSigma double 10.0 Blur intensity when scrolled (sigmaX & sigmaY).
isScrolled bool true Toggles scrolled glass blur and bottom border.
margin EdgeInsetsGeometry? null Outer margin (useful for floating pill mode).
borderRadius BorderRadius? null Rounded corner radius (useful for floating pill mode).
backgroundColor Color? Theme surface Background color when scrolled.
unScrolledBackgroundColor Color? Theme surface Background color when not scrolled.
borderColor Color? Theme outline Subtle bottom/surrounding border color.
borderWidth double 1.0 Border stroke width.
bottom PreferredSizeWidget? null Bottom widget (e.g. TabBar).
duration Duration 200ms Animation duration for blur/color transitions.

Blurred Bottom Navigation Bar (GlassBottomNavigationBar)

Frosted glass bottom navigation bar (also available via GlassBottomNavigationBar alias) with animated active tab transitions, haptic feedback, badge indicators, and support for both docked and floating pill styles.

💡 Important: Set extendBody: true on your Scaffold so that scrolling content passes and blurs underneath the bottom navigation bar.

1. Floating Pill Mode

Scaffold(
  extendBody: true,
  bottomNavigationBar: BlurredBottomNavigationBar(
    currentIndex: _currentIndex,
    onTap: (index) => setState(() => _currentIndex = index),
    margin: const EdgeInsets.fromLTRB(16, 0, 16, 16),
    borderRadius: BorderRadius.circular(24.0),
    blurSigma: 14.0,
    items: const [
      BlurredNavItem(
        icon: Icon(Icons.chat_bubble_outline),
        activeIcon: Icon(Icons.chat_bubble),
        label: 'Chats',
        badge: Text('3'),
      ),
      BlurredNavItem(
        icon: Icon(Icons.call_outlined),
        activeIcon: Icon(Icons.call),
        label: 'Calls',
      ),
      BlurredNavItem(
        icon: Icon(Icons.settings_outlined),
        activeIcon: Icon(Icons.settings),
        label: 'Settings',
      ),
    ],
  ),
  body: ListView(...),
)

2. Docked Mode

Scaffold(
  extendBody: true,
  bottomNavigationBar: BlurredBottomNavigationBar(
    currentIndex: _currentIndex,
    onTap: (index) => setState(() => _currentIndex = index),
    blurSigma: 12.0,
    items: const [
      BlurredNavItem(icon: Icon(Icons.home), label: 'Home'),
      BlurredNavItem(icon: Icon(Icons.explore), label: 'Explore'),
      BlurredNavItem(icon: Icon(Icons.person), label: 'Profile'),
    ],
  ),
  body: ListView(...),
)

3. Navigation Bar Parameters

Parameter Type Default Description
items List<BlurredNavItem> required List of items (min 2 items).
currentIndex int required Current active tab index.
onTap ValueChanged<int> required Callback when a tab is tapped.
blurSigma double 12.0 Blur intensity (sigmaX & sigmaY).
height double 64.0 Bar height (excluding bottom safe area).
margin EdgeInsetsGeometry? null Outer margin for floating mode.
borderRadius BorderRadius? null Corner radius for floating mode.
selectedItemColor Color? Theme primary Color of active tab icon and label.
unselectedItemColor Color? Theme text Color of inactive tab icons and labels.
showLabels bool true Whether to display text labels.
useSafeArea bool true Handles bottom safe area in docked mode.
enableHapticFeedback bool true Light haptic vibration on item selection.

Blurred Loading Overlay

Basic Usage (Default Cupertino Style):

BlurredLoadingOverlay(
  isLoading: _isLoading,
  child: YourContentWidget(),
)

With Different Loading Styles:

BlurredLoadingOverlay(
  isLoading: _isLoading,
  loadingStyle: LoadingStyle.pulseRing, // 20 styles available
  loadingColor: Colors.blue,
  loadingSize: 60.0,
  child: YourContentWidget(),
)

With Custom Loading Widget:

BlurredLoadingOverlay(
  isLoading: _isLoading,
  customLoadingWidget: CircularProgressIndicator(),
  child: YourContentWidget(),
)

With Header and Footer:

BlurredLoadingOverlay(
  isLoading: _isLoading,
  loadingStyle: LoadingStyle.breathingCircle,
  headerWidget: Text('Loading...', style: TextStyle(color: Colors.white)),
  footerWidget: Text('Please wait', style: TextStyle(color: Colors.white70)),
  child: YourContentWidget(),
)

Available Loading Styles:

  • cupertinoBox (default) - iOS-style spinner in a box
  • bouncingLineCircle/Square - Bouncing shapes
  • bouncingGridCircle/Square - 3x3 grid bounce
  • bumpingLineCircle/Square - Horizontal bump
  • fadingLineCircle/Square - Sequential fade
  • jumpingLineCircle/Square - Vertical jump
  • rotatingSquare - Rotating shape
  • flippingCircle/Square - Horizontal flip
  • doubleFlippingCircle/Square - 3D flip effect
  • fillingSquare - Fill and rotate
  • pulseRing - Expanding rings
  • orbitDots - Orbiting dots
  • breathingCircle - Expanding/contracting circle

Blurred Progress Loading

Circle Progress:

BlurredLoadingPercentage(
  isLoading: _isLoading,
  progress: _progressValue, // 0.0 to 100.0
  progressStyle: ProgressStyle.circle,
  child: YourContentWidget(),
)

Line Progress:

BlurredLoadingPercentage(
  isLoading: _isLoading,
  progress: _progressValue,
  progressStyle: ProgressStyle.line,
  progressColor: Colors.green,
  trackColor: Colors.white24,
  child: YourContentWidget(),
)

Libraries

blurred_overlay
A Flutter package to show frosted glass AppBars, bottom navigation bars, blurred dialogs, bottom sheets, drawers, and loading overlays using BackdropFilter.