Philip Feldmann
Philip Feldmann

Reputation: 8435

Why does Backdrop filter blur my entire app

I am trying to achieve a very similar effect to what was shown in the widget of the week video on flutter's channel: https://www.youtube.com/watch?v=dYRs7Q1vfYI#t=1m20s

On the right you see the desired result, on the left you see what's currently going on in my app. On the right my app, on the left the wanted result

The code I've been using is pretty similar to the one from the example video, using a Stack to position the Backdrop filter over my image. The rounded image and the blur over it are inside one widget, which will is placed inside another stack (along with the text at the bottom). Since I applied the filter only a small section of the image, I don't understand why entire app is blurred. Here's the code for the Image Widget:

Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size.width - 75;
    return Container(
      height: size,
      width: size,
      child: Stack(
        alignment: Alignment.center,
        children: <Widget>[
          Image(imageUri: "...", size: size - 30), // this is just a container with the image
          Positioned(
            top: 100,
            left: 100,
            bottom: 100,
            right: 100,
            child: BackdropFilter(
              filter: ImageFilter.blur(
                sigmaX: 5,
                sigmaY: 5,
              ),
              child: Container(
                color: Color(0x66FF0000),
              ),
            ),
          )
        ],
      ),
    );
  }
}

Upvotes: 36

Views: 19741

Answers (3)

hungtran273
hungtran273

Reputation: 1357

Another solution in 2021:

Apply clipBehavior: Clip.hardEdge to parent of BackdropFilter

Container(
  clipBehavior: Clip.hardEdge,
  decoration: const BoxDecoration(),
  child: BackdropFilter(
    filter: ImageFilter.blur(sigmaX: 2.0, sigmaY: 2.0),
    child: Container(
      color: Colors.black.withOpacity(0.2),
    ),
  ),
)

Explanation:
clipBehavior: Clip.hardEdge means overflow: none
If no clip, filter will overflow upward (in widget tree) until they meet clip.

Upvotes: 15

Salman Ali
Salman Ali

Reputation: 239

The solution is simply wrap the "BackDropFilter" with "CliprRect" widget. Like this:

CliprRect(child: BackDropFilter(child: "your widget"),),

Upvotes: 1

Philip Feldmann
Philip Feldmann

Reputation: 8435

It turns out the video is missing an important part from the documentation:

If there's no clip, the filter will be applied to the full screen.

So the solution is to wrap the filter into a ClipRect, as taken from the example:

ClipRect(  // <-- clips to the 200x200 [Container] below
        child: BackdropFilter(
          filter: ui.ImageFilter.blur(
            sigmaX: 5.0,
            sigmaY: 5.0,
          ),
          child: Container(
            alignment: Alignment.center,
            width: 200.0,
            height: 200.0,
            child: Text('Hello World'),
          ),
        ),
      ),

Upvotes: 125

Related Questions