简体   繁体   English

如何在Flutter中使用动态大小的小部件设置BackdropFilter

[英]How to set a BackdropFilter using dynamic-sized widgets in Flutter

I have a column: header with text, body with image, footer with text, all widgets have transparent backgrounds. 我有一列:带文本的标题,带图像的正文,带文本的页脚,所有小部件都有透明背景。 I want to set the background using a blur of the main image but I keep reaching dead ends. 我想使用主图像的模糊来设置背景,但是我一直走不通。

In some situations this would be straight forward but in my scenario the image could be of any size and aspect ratio, and I need the effect to be wrapped with the column. 在某些情况下,这很简单,但是在我的情况下,图像可以是任何大小和纵横比,并且我需要将效果包裹在列中。

Here are my two failed attempts: 这是我两次失败的尝试:

Method 1 方法1

I have a Stack with the image as the first item, then a BackdropFilter with ImageFilter blur, then my Column. 我有一个图像作为第一项的堆栈,然后是一个具有ImageFilter模糊的BackdropFilter,然后是我的列。 This works but the Image bleeds out from under the Column because of the image size (which can be any size). 这可以工作,但是由于图像大小(可以是任何大小),因此图像从列下方渗出。 I want to constrain it to the height of my Column. 我想将其限制为“专栏”的高度。

return Container(
      child: Stack(
        alignment: AlignmentDirectional.topCenter,
        children: <Widget>[
          Positioned.fill(child: Image.network(_imgUrl)),
          BackdropFilter(
              filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
              child: Container(
                decoration: BoxDecoration(color: Colors.white.withOpacity(0.0)),
              )),
          Container(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              // https://stackoverflow.com/a/41846093/3429021
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
                Header(),
                BodyPhoto(),
                Footer()
              ],
            ),
          ),
        ],
      ),

Method 2 方法2

Putting the column in a Container with a DecorationImage, which sizes the image perfectly, but I have no way of applying the blur effect. 将列放在带有DecorationImage的Container中,可以完美调整图像的大小,但是我无法应用模糊效果。

(_streamItem is my Column wrapped in a container) (_streamItem是包装在容器中的我的专栏)

body: Container(child: _streamItem,
          decoration: new BoxDecoration(image: DecorationImage(
              image: NetworkImage(_streamItem.imgUrl),
              fit: BoxFit.cover)
          )
      )

Any ideas? 有任何想法吗?

You can explicitly give a fix height to the container that contains the image, which will even look better. 您可以显式地给包含图像的容器指定一个固定高度,这看起来会更好。

In this example I have set three images of very different dimensions and has no problem rendering. 在此示例中,我设置了三个尺寸完全不同的图像,并且渲染没有问题。

Refer the below code: 请参考以下代码:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('So Help'),
      ),
      body: new ListView(
        children: <Widget>[
          MyContainer(
            imageUrl:
                'https://i.dailymail.co.uk/i/pix/2017/01/16/20/332EE38400000578-4125738-image-a-132_1484600112489.jpg',
          ),
          MyContainer(
            imageUrl:
                'http://static.guim.co.uk/sys-images/Guardian/Pix/pictures/2014/4/11/1397210130748/Spring-Lamb.-Image-shot-2-011.jpg',
          ),
          MyContainer(
            imageUrl:
                'http://wackymania.com/image/2011/6/vertical-panoramic-photography/vertical-panoramic-photography-15.jpg',
          ),
        ],
      ),
    );
  }
}

class MyContainer extends StatelessWidget {
  final String imageUrl;

  MyContainer({@required this.imageUrl});

  @override
  Widget build(BuildContext context) {
    return new Container(
      height: 300.0,
      child: new Stack(
        children: <Widget>[
          new Container(
            child: Image.network(
              this.imageUrl,
              width: MediaQuery.of(context).size.width,
              fit: BoxFit.cover,
            ),
          ),
          BackdropFilter(
            filter: Dui.ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
            child: new Container(
              color: Colors.transparent,
            ),
          ),
          new Container(
            height: 300.0,
            child: new Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                Container(
                  width: MediaQuery.of(context).size.width,
                ),
                Padding(
                  padding: const EdgeInsets.all(20.0),
                  child: new Text(
                    'Header',
                    style: new TextStyle(color: Colors.white),
                  ),
                ),
                new Expanded(
                  child: Image.network(imageUrl),
                ),
                Padding(
                  padding: const EdgeInsets.all(20.0),
                  child: new Text(
                    'Footer',
                    style: new TextStyle(color: Colors.white),
                  ),
                ),
              ],
            ),
          )
        ],
      ),
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM