如何在Flutter中模糊一个容器或任何小部件

13

我正在尝试在一个容器小部件上实现模糊效果,就像这样:

期望效果:

enter image description here

我尝试使用BackdropFilterImageFilter.blur滤镜来实现它,但没有任何帮助。

代码:

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,
          ),
        ),
      ]
    ),
  )

输出:

在此输入图片描述


你想要模糊什么?是想要模糊外圆还是整个正方形容器? - Dhrumil Shah - dhuma1981
我只想模糊外圈。 - ImMathan
8个回答

15
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),
      ),
    ),
  ),
);

在Flutter中创建模糊容器的最佳方法是使用ClipRect来避免整个屏幕模糊。

14

Widgets 没有直接模糊自身的方法(据我所知)。但是您可以通过使用 CustomPainter 来实现它。

MaskFilter.blur(BlurStyle.normal, blurSigma) 可以向任何您想要绘制的小部件添加模糊效果。

例如,

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;
  }
}

您可以使用CircleBlurPainter和带有foregroundPainter属性的CustomPaint小部件。

blur_widget.dart

class BlurWidget extends StatelessWidget {

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

模糊的小部件输出


13

以下是制作模糊图像的示例:

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)),
            ),
          ),
      );

关于你的案例

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)),
            ),
          ),
        )
      ]
  ),
);

我之前尝试过类似的东西,但实际上并没有模糊容器。 - ImMathan
我有一个堆栈,其中包含一个img和一个带有黑色54颜色的容器以及容器上的文本小部件。我想只模糊容器(堆栈的中间元素),如何实现? - Mahdi-Jafaree
你需要将要模糊的容器之外的文本放置在容器外面。 - Andrii Turkovskyi
这个程序占据了整个屏幕,而不仅仅是容器。我已经在backdropfilter内部的容器中设置了高度,在backdropfilter之上以及在stack本身之上。 - Hassan Ansari

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

6
提供容器的剪辑属性。
 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)),
),

0
你可以简单地做的是,将小部件包裹在订单中。
材料 ClipRRect BackdropFilter

        Material(
            color: Colors.transparent,
            child: ClipRRect(
              child: BackdropFilter(
                filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
                child: Container(
                  padding: const EdgeInsets.symmetric(
                    horizontal: 8,
                    vertical: 8,
                  ),
                  child: Text('Blurry Text'),
                ),
              ),
            ),
          );


0

这实际上不是模糊,而是透明度。高斯模糊滤镜在纯色(如您的外圆)中没有效果。根本没有什么可以模糊的。

这可以实现所需的效果:

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),
      ]),
    )

将输出这个:

enter image description here


-2

虽然我知道回答有点晚,但我想尝试一下帮助那些正在阅读此内容的人们:D

在这种情况下,您可以使用以下简单方法模糊容器:

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

比你想象的更容易,是吧?祝你编程愉快!


1
那不是模糊,而是透明度(即使这可能是 OP 所要求的内容);) - user3249027

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接