Как установить BackdropFilter с помощью виджетов динамического размера во Flutter - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть столбец: заголовок с текстом, тело с изображением, нижний колонтитул с текстом, все виджеты имеют прозрачный фон. Я хочу установить фон, используя размытие основного изображения, но продолжаю заходить в тупики.

В некоторых ситуациях это может быть прямым, но в моем сценарии изображение может иметь любой размер и соотношение сторон, и мне нужно обернуть эффект столбцом.

Вот две мои неудачные попытки:

Метод 1

У меня есть стек с изображением в качестве первого элемента, затем BackdropFilter с размытием ImageFilter, затем мой столбец. Это работает, но изображение выпадает из-под столбца из-за размера изображения (который может быть любого размера). Я хочу ограничить его высотой моей колонны.

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

Метод 2

Помещение столбца в Контейнер с DecoImage, который идеально подходит к размеру изображения, но у меня нет способа применить эффект размытия.

(_ streamItem - моя колонка, завернутая в контейнер)

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

Есть идеи?

1 Ответ

0 голосов
/ 17 сентября 2018

Вы можете явно указать фиксированную высоту контейнера, содержащего изображение, которое будет выглядеть даже лучше.

В этом примере я установил три изображения очень разных размеров и без проблем рендеринг.

См. Код ниже:

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