How to blur a Container or Any widget in Flutter

Viewed 27319

I am trying to achieve a blur effect on a Container widget something like this.

Expectation:

enter image description here

I tried to achieve it with BackdropFilter with ImageFilter.blur filter but it's not of any help.

Code

child: Container(
    child: Stack(
      children: <Widget>[
        BackdropFilter(
          filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
          child: Container(
            decoration: BoxDecoration(
                shape: BoxShape.circle,
                color: color
            ),
            height: 60,
            width: 60,
          ),
        ),
        Positioned(
          left: 15,
          top: 15,
          child: Container(
            decoration: BoxDecoration(
                shape: BoxShape.circle,
                color: Colors.lightBlue
            ),
            height: 30,
            width: 30,
          ),
        ),
      ]
    ),
  )

Output:

enter image description here

7 Answers

Here is example how to make blurred image:

Container(
        decoration: BoxDecoration(
          image: DecorationImage(image: NetworkImage(imgUrl), fit: BoxFit.cover),
        ),
        child: BackdropFilter(
            filter: ui.ImageFilter.blur(sigmaX: 4.0, sigmaY: 4.0),
            child: Container(
              decoration: BoxDecoration(color: Colors.white.withOpacity(0.0)),
            ),
          ),
      );

And regarding to your case

Container(
  child: Stack(
      children: <Widget>[
        Container(
            decoration: BoxDecoration(
                shape: BoxShape.circle,
                color: Colors.red
            ),
            height: 60,
            width: 60,
          ),
        Positioned(
          left: 15,
          top: 15,
          child: Container(
            decoration: BoxDecoration(
                shape: BoxShape.circle,
                color: Colors.lightBlue
            ),
            height: 30,
            width: 30,
          ),
        ),
        Container(
          child: BackdropFilter(
            filter: ui.ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
            child: Container(
              decoration: BoxDecoration(color: Colors.white.withOpacity(0.0)),
            ),
          ),
        )
      ]
  ),
);

Widgets do not have a direct way to blur itself(as for as I know). But you can achieve it by using a CustomPainter.

MaskFilter.blur(BlurStyle.normal, blurSigma) can add the blur effect to any widget you want to draw yourself.

For example,

circle_blur_painter.dart

class CircleBlurPainter extends CustomPainter {

  CircleBlurPainter({@required this.circleWidth, this.blurSigma});

  double circleWidth;
  double blurSigma;

  @override
  void paint(Canvas canvas, Size size) {
    Paint line = new Paint()
      ..color = Colors.lightBlue
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.stroke
      ..strokeWidth = circleWidth
      ..maskFilter = MaskFilter.blur(BlurStyle.normal, blurSigma);
    Offset center = new Offset(size.width / 2, size.height / 2);
    double radius = min(size.width / 2, size.height / 2);
    canvas.drawCircle(center, radius, line);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

And you can use the CircleBlurPainter with a CustomPaint widget with foregroundPainter attribute.

blur_widget.dart

class BlurWidget extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return CustomPaint(foregroundPainter: CircleBlurPainter(circleWidth: 30, blurSigma: 3.0));
  }
}

blurred widget output

Container(
  height: 300,
  width: MediaQuery.of(context).size.width,
  decoration: BoxDecoration(
    image: DecorationImage(
      image: NetworkImage('your image url'),
      fit: BoxFit.cover
    ),
  ),
  child: ClipRect(
    child: BackdropFilter(
      filter: ImageFilter.blur(sigmaX: 2.0, sigmaY: 2.0),
      child: Container(
        color: Colors.black.withOpacity(0.1),
      ),
    ),
  ),
);

The best way to make blur container in flutter and I am using clipRect to avoid whole screen blur.

child: BackdropFilter(
    filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
    child: Container( 
      height: 125,
      color: Colors.black54, 
      child: YourWidget()
   ),
)

Provide Clip property to your Container

 Container(
  padding: EdgeInsets.all(12),
  decoration: BoxDecoration(
    shape: BoxShape.circle,
  ),
  clipBehavior: Clip.antiAlias,
  child: BackdropFilter(
      filter: ImageFilter.blur(sigmaX: 3, sigmaY: 3),
      child:
          const Icon(FontAwesomeIcons.play, size: 15)),
),

That's actually not blur, just opacity. Gaussian blur filter has no effect in a plain color (like your outer circle). There's simply nothing to blur.

This could achieve the desired effect:

Container(
      height: 120,
      width: 120,
      color: Colors.blue.shade900,
      child: Stack(alignment: Alignment.center, children: <Widget>[
        Container(
            decoration:
                BoxDecoration(shape: BoxShape.circle, color: Colors.amber),
            height: 60,
            width: 60),
        Container(
            decoration: BoxDecoration(
                shape: BoxShape.circle, color: Colors.amber.withOpacity(.3)),
            height: 80,
            width: 80),
      ]),
    )

Will output this:

enter image description here

Well i know its little bit late to answer but i want to try my chance to help people out there who is reading this now :D

In this case you can just blur a container with this easy way below;

      Container(
        color: Colors.black.withOpacity(0.8),
      ),

Easier than you think, no? Have good coding!

Related