How to Blur Background Widgets Using BackdropFilter in Flutter

This how to blur background widgets using backdropfilter is posted by seven.srikanth at 5/3/2025 5:49:02 PM



<h1 id="how-to-blur-background-widgets-using-backdropfilter-in-flutter">How to Blur Background Widgets Using BackdropFilter in Flutter</h1> <p>Creating a frosted glass effect or blurred UI components has become a popular design trend in modern applications. Flutter provides the <code>BackdropFilter</code> widget to easily achieve this effect by applying various filters to the content behind a widget. In this tutorial, we'll explore how to create beautiful blur effects in your Flutter applications.</p> <h2 id="understanding-backdropfilter">Understanding BackdropFilter</h2> <p>The <code>BackdropFilter</code> widget in Flutter applies a filter to all the widgets that are painted before it in the same layer. It's commonly used with the <code>ImageFilter.blur</code> filter to create frosted glass or blur effects.</p> <p>Here's the basic structure:</p> <pre>BackdropFilter( filter: ImageFilter.blur( sigmaX: 5.0, sigmaY: 5.0, ), child: Container( // Your content here ), ) </pre> <p>The <code>sigmaX</code> and <code>sigmaY</code> parameters control the amount of blur in the horizontal and vertical directions.</p> <p><img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAwIiBoZWlnaHQ9IjMwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8IS0tIEJhY2tncm91bmQgLS0+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjUwMCIgaGVpZ2h0PSIzMDAiIGZpbGw9IiNmYWZhZmEiLz4KICAKICA8IS0tIENvbG9yZnVsIEJhY2tncm91bmQgQ2lyY2xlcyAtLT4KICA8Y2lyY2xlIGN4PSIxMDAiIGN5PSIxNTAiIHI9IjcwIiBmaWxsPSJyZ2JhKDc3LCAxODIsIDI1NSwgMC43KSIvPgogIDxjaXJjbGUgY3g9IjIwMCIgY3k9IjEwMCIgcj0iNjAiIGZpbGw9InJnYmEoMjU1LCA5OSwgMTMyLCAwLjcpIi8+CiAgPGNpcmNsZSBjeD0iMzAwIiBjeT0iMTgwIiByPSI4MCIgZmlsbD0icmdiYSgyNTUsIDE5OSwgMCwgMC41KSIvPgogIAogIDwhLS0gRGl2aWRlciAtLT4KICA8bGluZSB4MT0iMjUwIiB5MT0iMCIgeDI9IjI1MCIgeTI9IjMwMCIgc3Ryb2tlPSIjYWFhIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1kYXNoYXJyYXk9IjUsIDUiLz4KICAKICA8IS0tIExhYmVscyAtLT4KICA8dGV4dCB4PSIxMjUiIHk9IjI4MCIgZm9udC1mYW1pbHk9IkFyaWFsIiBmb250LXNpemU9IjE0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj5PcmlnaW5hbDwvdGV4dD4KICA8dGV4dCB4PSIzNzUiIHk9IjI4MCIgZm9udC1mYW1pbHk9IkFyaWFsIiBmb250LXNpemU9IjE0IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj5XaXRoIEJhY2tkcm9wRmlsdGVyIEJsdXI8L3RleHQ+CiAgCiAgPCEtLSBCbHVycmVkIFNpZGUgKFNpbXVsYXRlZCBCbHVyKSAtLT4KICA8ZGVmcz4KICAgIDxmaWx0ZXIgaWQ9ImJsdXJGaWx0ZXIiPgogICAgICA8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSI1IiAvPgogICAgPC9maWx0ZXI+CiAgPC9kZWZzPgogIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI1MCwgMCkiPgogICAgPGcgZmlsdGVyPSJ1cmwoI2JsdXJGaWx0ZXIpIj4KICAgICAgPGNpcmNsZSBjeD0iMTAwIiBjeT0iMTUwIiByPSI3MCIgZmlsbD0icmdiYSg3NywgMTgyLCAyNTUsIDAuNykiLz4KICAgICAgPGNpcmNsZSBjeD0iMjAwIiBjeT0iMTAwIiByPSI2MCIgZmlsbD0icmdiYSgyNTUsIDk5LCAxMzIsIDAuNykiLz4KICAgICAgPGNpcmNsZSBjeD0iMzAwIiBjeT0iMTgwIiByPSI4MCIgZmlsbD0icmdiYSgyNTUsIDE5OSwgMCwgMC41KSIvPgogICAgPC9nPgogICAgPCEtLSBHbGFzc3kgQ29udGFpbmVyIC0tPgogICAgPHJlY3QgeD0iNzUiIHk9IjExMCIgd2lkdGg9IjE1MCIgaGVpZ2h0PSI4MCIgcng9IjEwIiByeT0iMTAiIGZpbGw9InJnYmEoMjU1LCAyNTUsIDI1NSwgMC4zKSIgc3Ryb2tlPSJyZ2JhKDI1NSwgMjU1LCAyNTUsIDAuNSkiIHN0cm9rZS13aWR0aD0iMSIvPgogICAgPHRleHQgeD0iMTUwIiB5PSIxNTUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIxNCIgZmlsbD0id2hpdGUiIHRleHQtYW5jaG9yPSJtaWRkbGUiPkZyb3N0ZWQgR2xhc3MgRWZmZWN0PC90ZXh0PgogIDwvZz4KICAKICA8IS0tIE9yaWdpbmFsIENvbnRhaW5lciAtLT4KICA8cmVjdCB4PSI3NSIgeT0iMTEwIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjgwIiByeD0iMTAiIHJ5PSIxMCIgZmlsbD0icmdiYSgyNTUsIDI1NSwgMjU1LCAwLjcpIiBzdHJva2U9IiNjY2MiIHN0cm9rZS13aWR0aD0iMSIvPgogIDx0ZXh0IHg9IjE1MCIgeT0iMTU1IiBmb250LWZhbWlseT0iQXJpYWwiIGZvbnQtc2l6ZT0iMTQiIGZpbGw9IiMzMzMiIHRleHQtYW5jaG9yPSJtaWRkbGUiPlJlZ3VsYXIgQ29udGFpbmVyPC90ZXh0PgogIAogIDwhLS0gQ29kZSBBbm5vdGF0aW9ucyAtLT4KICA8dGV4dCB4PSIxNTAiIHk9IjIyMCIgZm9udC1mYW1pbHk9Im1vbm9zcGFjZSIgZm9udC1zaXplPSIxMCIgZmlsbD0iIzY2NiIgdGV4dC1hbmNob3I9Im1pZGRsZSI+Q29udGFpbmVyKGNvbG9yOiBDb2xvcnMud2hpdGUud2l0aE9wYWNpdHkoMC43KSk8L3RleHQ+CiAgCiAgPHRleHQgeD0iMzc1IiB5PSIyMjAiIGZvbnQtZmFtaWx5PSJtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMTAiIGZpbGw9IiM2NjYiIHRleHQtYW5jaG9yPSJtaWRkbGUiPkJhY2tkcm9wRmlsdGVyKGZpbHRlcjogSW1hZ2VGaWx0ZXIuYmx1cihzaWdtYVg6IDUsIHNpZ21hWTogNSkpPC90ZXh0PgogIDx0ZXh0IHg9IjM3NSIgeT0iMjM1IiBmb250LWZhbWlseT0ibW9ub3NwYWNlIiBmb250LXNpemU9IjEwIiBmaWxsPSIjNjY2IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj5Db250YWluZXIoY29sb3I6IENvbG9ycy53aGl0ZS53aXRoT3BhY2l0eSgwLjMpKTwvdGV4dD4KICAKICA8IS0tIFNtYWxsIEluZGljYXRvcnMgLS0+CiAgPGNpcmNsZSBjeD0iMTUwIiBjeT0iNjUiIHI9IjMiIGZpbGw9IiM2NjYiLz4KICA8cGF0aCBkPSJNIDE1MCA2NSBMIDE1MCAxMDAiIHN0cm9rZT0iIzY2NiIgc3Ryb2tlLXdpZHRoPSIxIiBzdHJva2UtZGFzaGFycmF5PSIyLDIiLz4KICAKICA8Y2lyY2xlIGN4PSI0MDAiIGN5PSI2NSIgcj0iMyIgZmlsbD0iIzY2NiIvPgogIDxwYXRoIGQ9Ik0gNDAwIDY1IEwgNDAwIDEwMCIgc3Ryb2tlPSIjNjY2IiBzdHJva2Utd2lkdGg9IjEiIHN0cm9rZS1kYXNoYXJyYXk9IjIsMiIvPgo8L3N2Zz4=" alt="Blur Effect Visualization" /></p> <h2 id="basic-implementation">Basic Implementation</h2> <p>Let's start with a simple example of how to implement a blur effect:</p> <pre>import &#39;package:flutter/material.dart&#39;; import &#39;dart:ui&#39;;

class BlurExample extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(&#39;Backdrop Filter Example&#39;), ), body: Stack( children: [ // Background Container( decoration: BoxDecoration( image: DecorationImage( image: NetworkImage(&#39;https://picsum.photos/id/1015/1000/800&#39;), fit: BoxFit.cover, ), ), ),

      // Blurred Container
      Center(
        child: ClipRRect(
          borderRadius: BorderRadius.circular(20),
          child: BackdropFilter(
            filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
            child: Container(
              width: 300,
              height: 200,
              decoration: BoxDecoration(
                color: Colors.white.withOpacity(0.2),
                borderRadius: BorderRadius.circular(20),
                border: Border.all(
                  color: Colors.white.withOpacity(0.2),
                  width: 1.5,
                ),
              ),
              child: Center(
                child: Text(
                  &amp;#39;Frosted Glass Effect&amp;#39;,
                  style: TextStyle(
                    fontSize: 24,
                    fontWeight: FontWeight.bold,
                    color: Colors.white,
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    ],
  ),
);

} } </pre> <p>In this example:</p> <ol> <li>We create a <code>Stack</code> to layer our components</li> <li>The background is a full-screen image</li> <li>We wrap the <code>BackdropFilter</code> with <code>ClipRRect</code> to constrain the blur effect to our container's boundaries</li> <li>The semi-transparent white container creates the frosted glass appearance</li> </ol> <h2 id="important-notes-about-backdropfilter">Important Notes About BackdropFilter</h2> <p>There are a few important things to understand about how <code>BackdropFilter</code> works:</p> <ol> <li><p><strong>It Affects Widgets Below It</strong>: <code>BackdropFilter</code> applies its filter to all widgets that are painted before it in the same layer.</p> </li> <li><p><strong>Clipping is Important</strong>: Always wrap your <code>BackdropFilter</code> with a clipping widget (like <code>ClipRect</code> or <code>ClipRRect</code>) to constrain the filter effect to a specific area.</p> </li> <li><p><strong>Performance Considerations</strong>: Blur operations are computationally expensive. Use them judiciously to avoid performance issues.</p> </li> </ol> <h2 id="creating-a-blurred-app-bar">Creating a Blurred App Bar</h2> <p>Let's create a customized blurred app bar:</p> <pre>class BlurredAppBar extends StatelessWidget { final String title;

const BlurredAppBar({Key? key, required this.title}) : super(key: key);

@override Widget build(BuildContext context) { return ClipRect( child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), child: AppBar( backgroundColor: Colors.transparent, elevation: 0, title: Text(title), flexibleSpace: Container( decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), ), ), ), ), ); } } </pre> <p>Usage:</p> <pre>Scaffold( extendBodyBehindAppBar: true, appBar: PreferredSize( preferredSize: Size.fromHeight(kToolbarHeight), child: BlurredAppBar(title: &#39;Blurred App Bar&#39;), ), body: Container( decoration: BoxDecoration( image: DecorationImage( image: NetworkImage(&#39;https://picsum.photos/id/1018/1000/800&#39;), fit: BoxFit.cover, ), ), ), ) </pre> <h2 id="creating-a-blurred-bottom-navigation-bar">Creating a Blurred Bottom Navigation Bar</h2> <p>Similarly, we can create a blurred bottom navigation bar:</p> <pre>class BlurredBottomNavBar extends StatelessWidget { final int currentIndex; final Function(int) onTap;

const BlurredBottomNavBar({ Key? key, required this.currentIndex, required this.onTap, }) : super(key: key);

@override Widget build(BuildContext context) { return ClipRect( child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), child: Container( decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), border: Border( top: BorderSide( color: Colors.white.withOpacity(0.2), width: 1.0, ), ), ), child: BottomNavigationBar( backgroundColor: Colors.transparent, elevation: 0, currentIndex: currentIndex, onTap: onTap, selectedItemColor: Colors.white, unselectedItemColor: Colors.white70, type: BottomNavigationBarType.fixed, items: [ BottomNavigationBarItem( icon: Icon(Icons.home), label: &#39;Home&#39;, ), BottomNavigationBarItem( icon: Icon(Icons.search), label: &#39;Search&#39;, ), BottomNavigationBarItem( icon: Icon(Icons.favorite), label: &#39;Favorites&#39;, ), BottomNavigationBarItem( icon: Icon(Icons.person), label: &#39;Profile&#39;, ), ], ), ), ), ); } } </pre> <h2 id="creating-a-blurred-modal-bottom-sheet">Creating a Blurred Modal Bottom Sheet</h2> <p>A blurred modal bottom sheet can add an elegant touch to your app:</p> <pre>void showBlurredBottomSheet(BuildContext context) { showModalBottomSheet( context: context, backgroundColor: Colors.transparent, builder: (context) { return ClipRRect( borderRadius: BorderRadius.vertical(top: Radius.circular(20)), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15), child: Container( padding: EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), borderRadius: BorderRadius.vertical(top: Radius.circular(20)), border: Border.all( color: Colors.white.withOpacity(0.2), width: 1.5, ), ), height: 300, child: Column( children: [ Container( width: 40, height: 5, margin: EdgeInsets.only(bottom: 20), decoration: BoxDecoration( color: Colors.white.withOpacity(0.5), borderRadius: BorderRadius.circular(2.5), ), ), Text( &#39;Blurred Bottom Sheet&#39;, style: TextStyle( fontSize: 22, fontWeight: FontWeight.bold, color: Colors.white, ), ), SizedBox(height: 15), Text( &#39;This bottom sheet uses BackdropFilter to create a beautiful blur effect.&#39;, style: TextStyle( color: Colors.white.withOpacity(0.8), fontSize: 16, ), textAlign: TextAlign.center, ), Spacer(), ElevatedButton( onPressed: () =&gt; Navigator.pop(context), child: Text(&#39;Close&#39;), style: ElevatedButton.styleFrom( primary: Colors.white.withOpacity(0.3), onPrimary: Colors.white, shadowColor: Colors.transparent, ), ), ], ), ), ), ); }, ); } </pre> <h2 id="creating-a-reusable-frosted-glass-container">Creating a Reusable Frosted Glass Container</h2> <p>Let's create a reusable frosted glass container widget:</p> <pre>class FrostedGlassBox extends StatelessWidget { final double width; final double height; final Widget child; final double blur; final double borderRadius; final Color borderColor; final Color backgroundColor;

const FrostedGlassBox({ Key? key, required this.width, required this.height, required this.child, this.blur = 10, this.borderRadius = 20, this.borderColor = Colors.white30, this.backgroundColor = Colors.white30, }) : super(key: key);

@override Widget build(BuildContext context) { return ClipRRect( borderRadius: BorderRadius.circular(borderRadius), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: blur, sigmaY: blur), child: Container( width: width, height: height, decoration: BoxDecoration( color: backgroundColor, borderRadius: BorderRadius.circular(borderRadius), border: Border.all( color: borderColor, width: 1.5, ), ), child: child, ), ), ); } } </pre> <p>Usage:</p> <pre>FrostedGlassBox( width: 300, height: 200, child: Center( child: Text( &#39;Reusable Frosted Glass&#39;, style: TextStyle( color: Colors.white, fontSize: 22, fontWeight: FontWeight.bold, ), ), ), ) </pre> <h2 id="performance-optimization">Performance Optimization</h2> <p>Blur operations can be computationally expensive. Here are some tips to optimize performance:</p> <ol> <li><p><strong>Limit the Size</strong>: Apply blur to smaller areas rather than the entire screen.</p> </li> <li><p><strong>Reduce Blur Complexity</strong>: Lower sigma values require less computation.</p> </li> <li><p><strong>Avoid Animating Blur Values</strong>: Changing blur values in animations can be very expensive.</p> </li> <li><p><strong>Consider Using Static Blurred Images</strong>: For static backgrounds, pre-blur the image instead of using <code>BackdropFilter</code>.</p> </li> <li><p><strong>Use RepaintBoundary</strong>: Wrap widgets that don't change often with <code>RepaintBoundary</code> to reduce unnecessary repainting.</p> </li> </ol> <pre>RepaintBoundary( child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), child: Container(/* ... */), ), ) </pre> <h2 id="common-use-cases-for-backdrop-filter">Common Use Cases for Backdrop Filter</h2> <h3 id="photo-gallery-overlays">1. Photo Gallery Overlays</h3> <pre>Stack( children: [ Image.network(&#39;https://example.com/image.jpg&#39;), Positioned( bottom: 0, left: 0, right: 0, child: ClipRect( child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), child: Container( padding: EdgeInsets.all(16), color: Colors.black.withOpacity(0.3), child: Text( &#39;Image Caption&#39;, style: TextStyle(color: Colors.white), ), ), ), ), ), ], ) </pre> <h3 id="blurred-login-background">2. Blurred Login Background</h3> <pre>class BlurredLoginScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ // Background image Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage(&#39;assets/background.jpg&#39;), fit: BoxFit.cover, ), ), ),

      // Blurred background
      BackdropFilter(
        filter: ImageFilter.blur(sigmaX: 3, sigmaY: 3),
        child: Container(
          color: Colors.black.withOpacity(0.1),
        ),
      ),
      
      // Login form
      Center(
        child: FrostedGlassBox(
          width: 300,
          height: 400,
          borderRadius: 15,
          backgroundColor: Colors.white.withOpacity(0.15),
          child: Padding(
            padding: EdgeInsets.all(20),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(
                  &amp;#39;Login&amp;#39;,
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 24,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                SizedBox(height: 30),
                TextField(
                  decoration: InputDecoration(
                    hintText: &amp;#39;Email&amp;#39;,
                    filled: true,
                    fillColor: Colors.white.withOpacity(0.3),
                    border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(10),
                      borderSide: BorderSide.none,
                    ),
                  ),
                ),
                SizedBox(height: 15),
                TextField(
                  obscureText: true,
                  decoration: InputDecoration(
                    hintText: &amp;#39;Password&amp;#39;,
                    filled: true,
                    fillColor: Colors.white.withOpacity(0.3),
                    border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(10),
                      borderSide: BorderSide.none,
                    ),
                  ),
                ),
                SizedBox(height: 30),
                ElevatedButton(
                  onPressed: () {},
                  child: Text(&amp;#39;Login&amp;#39;),
                  style: ElevatedButton.styleFrom(
                    padding: EdgeInsets.symmetric(
                      horizontal: 50,
                      vertical: 15,
                    ),
                    primary: Colors.white.withOpacity(0.3),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    ],
  ),
);

} } </pre> <h2 id="troubleshooting-common-issues">Troubleshooting Common Issues</h2> <h3 id="backdropfilter-is-not-blurring-anything">1. "BackdropFilter is not blurring anything"</h3> <p>Ensure that:</p> <ul> <li>The <code>BackdropFilter</code> is actually positioned on top of other widgets in a Stack</li> <li>You've wrapped it with a clipping widget like <code>ClipRect</code></li> <li>There's visual content underneath to be blurred</li> </ul> <h3 id="blur-effect-is-applying-to-the-entire-screen">2. "Blur effect is applying to the entire screen"</h3> <p>Always wrap your <code>BackdropFilter</code> with a clipping widget to constrain its effect:</p> <pre>ClipRect( child: BackdropFilter( // Your filter ), ) </pre> <h3 id="performance-is-slow-when-using-blur">3. "Performance is slow when using blur"</h3> <p>Reduce the blur complexity or limit its use:</p> <ul> <li>Use lower sigma values</li> <li>Apply blur to smaller areas</li> <li>Consider pre-blurred images for static content</li> </ul> <h2 id="conclusion">Conclusion</h2> <p>The <code>BackdropFilter</code> widget is a powerful tool in Flutter that allows you to create stunning blur effects and frosted glass interfaces. By combining it with other widgets like <code>ClipRRect</code> and semi-transparent containers, you can create modern, visually appealing UIs.</p> <p>Remember to use blur effects judiciously to maintain good performance, especially on less powerful devices. For static backgrounds, consider pre-blurring images rather than using real-time blurs.</p> <p>By following the techniques and examples in this guide, you'll be able to implement beautiful blur effects in your Flutter applications, enhancing the visual appeal and user experience of your app.</p> <p>Happy coding!</p>


Tags: flutter,markdown,generated








0 Comments
Login to comment.
Recent Comments