Эффект размытия по Гауссу теперь должен использоваться во многих местах, я думаю, что чуть не потерял свою жизнь, когда реализовал его на Android, так каково было бы реализовать его во Flutter?
Что такое BackdropFilter и как им пользоваться
Flutter предоставляет BackdropFilter для достижения эффекта размытия по Гауссу, откройте исходный код как обычно:
class BackdropFilter extends SingleChildRenderObjectWidget {
/// Creates a backdrop filter.
///
/// The [filter] argument must not be null.
const BackdropFilter({
Key key,
@required this.filter,
Widget child,
}) : assert(filter != null),
super(key: key, child: child);
/// The image filter to apply to the existing painted content before painting the child.
///
/// For example, consider using [ImageFilter.blur] to create a backdrop
/// blur effect
final ui.ImageFilter filter;
}
Вы можете видеть, что вы должны пройтиImageFilter filter
, и в примечании также говорится
For example, consider using [ImageFilter.blur] to create a backdrop blur effect
Например, рассмотрите возможность использования ImageFilter.blur для создания эффекта размытия фона.
Более того, над классом есть длинный комментарий:
/// A widget that applies a filter to the existing painted content and then
/// paints [child].
///
/// The filter will be applied to all the area within its parent or ancestor
/// widget's clip. If there's no clip, the filter will be applied to the full
/// screen.
///
/// {@youtube 560 315 https://www.youtube.com/watch?v=dYRs7Q1vfYI}
///
/// {@tool sample}
/// If the [BackdropFilter] needs to be applied to an area that exactly matches
/// its child, wraps the [BackdropFilter] with a clip widget that clips exactly
/// to that child.
///
/// ```dart
/// Stack(
/// fit: StackFit.expand,
/// children: <Widget>[
/// Text('0' * 10000),
/// Center(
/// child: 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'),
/// ),
/// ),
/// ),
/// ),
/// ],
/// )
/// ```
Что самое главное, скажу: Если вы не установите его размер, этот компонент будет на весь экран.
Потом!Он выпустил видео на YouTube! Также есть демо
Нечего сказать, давайте запустим официальную демонстрацию напрямую, чтобы увидеть, каков эффект:
Я чуть не ослеп, когда эта куча нулей появилась перед моими глазами.
Однако вы можете видеть, что с помощью BackdropFilter очень просто добиться эффекта размытия по Гауссу.
Пользовательский гауссовский размытый компонент
Затем мы можем инкапсулировать несколько элементов управления с гауссовым размытом на заднем плане в соответствии с идеей демонстрации:
class BlurOvalWidget extends StatelessWidget {
final Widget _widget;
double _padding = 10;
BlurOvalWidget(this._widget, {double padding = 0}) {
if (padding != 0) this._padding = padding;
}
@override
Widget build(BuildContext context) {
return ClipOval(
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 10,
sigmaY: 10,
),
child: Container(
color: Colors.white10,
padding: EdgeInsets.all(_padding),
child: _widget,
),
),
);
}
}
Мы используем виджет без сохранения состояния, и конструктору необходимо передать виджет для размещения на размытом фоне.
Тогда наш метод построения напрямую возвращает круговой размытый фон.Значение горизонтального и вертикального размытия равно 10. Чем больше значение, тем больше эффект размытия.
Вы не можете просто иметь круглый размытый фон, а затем прямоугольник со скругленными углами:
class BlurRectWidget extends StatelessWidget {
final Widget _widget;
double _padding = 10;
BlurRectWidget(this._widget, {double padding = 0}) {
if (padding != 0) this._padding = padding;
}
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 50),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10)),
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 20,
sigmaY: 20,
),
child: Container(
color: Colors.white10,
padding: EdgeInsets.all(_padding),
child: _widget,
),
),
),
);
}
}
Код в основном такой же, за исключением того, что ClipOval заменен на ClipRRect.
Теперь мы используем упакованные два виджета для реализации относительно простой страницы:
В тексте выше используется прямоугольник со скругленными углами, который мы определили, а в тексте ниже используется определенный нами круг.
Код выглядит следующим образом, он относительно прост, это обычная строительная страница:
class _BackdropFilterPageState extends State<BackdropFilterPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BackdropFilterPageState'),
),
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Image.asset(
'images/bg.jpg',
fit: BoxFit.cover,
),
Center(
child: BlurRectWidget(
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'BackdropFilter class',
style: TextStyle(
fontSize: 16,
color: Colors.white,
),
),
Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Text(
'A widget that applies a filter to the existing painted content and then paints child.'
'The filter will be applied to all the area within its parent or ancestor widget\'s clip. If there\'s no clip, the filter will be applied to the full screen.',
style: TextStyle(fontSize: 14, color: Colors.black87),
textAlign: TextAlign.justify,
),
),
],
),
),
),
Container(
alignment: Alignment.bottomCenter,
margin: EdgeInsets.only(bottom: 150),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
BlurOvalWidget(
IconButton(
onPressed: (){
Navigator.of(context).push(MaterialPageRoute(builder: (context){
return BlurImagePage();
}));
},
icon: Icon(
Icons.favorite,
color: Colors.white,
),
iconSize: 30,
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 50.0),
child: BlurOvalWidget(
Icon(
Icons.share,
color: Colors.white,
size: 30,
),
),
),
BlurOvalWidget(
Icon(
Icons.bookmark,
color: Colors.white,
size: 30,
),
),
],
),
),
],
),
);
}
}
Как использовать размытие по Гауссу в качестве переднего плана
В это время кто-то спрашивал, можно ли поставить размытие только на задний план, его нельзя использовать как передний план?
Конечно можно, иначе на что я трачу столько денег?
Сначала взгляните на рендеры:
Как же хочется этого ощущения🌝, есть ли желание перезарядиться!
Конечно, этот эффект очень просто реализовать: нам нужно только установить дочерний элемент BackdropFilter как Container(), установить цвет (здесь я использую Colors.white10) и поместить его в стек.
код показывает, как показано ниже:
class BlurImagePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.center,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child: Image.asset(
'images/wanimal.png',
fit: BoxFit.cover,
),
),
Positioned.fill(
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 15,
sigmaY: 15,
),
child: Container(
color: Colors.white10,
),
),
),
RaisedButton(
textColor: Colors.white,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(5))),
color: Colors.orangeAccent,
child: Text('充钱查看更多', style: TextStyle(fontSize: 16),),
onPressed: (){},
)
],
)),
);
}
}
Сначала поставьте виджет, который нам нужно покрыть, затем поставьте наш нечеткий виджет, а потом пусть пользователь берет деньги.
резюме
BackdropFilter может не только создавать эффект размытия по Гауссу, но также может использоваться для поворота, наклона и т. д.
Просто мы часто используем размытие по Гауссу, и принцип тот же.
Чтобы узнать больше, вы можете перейти на официальный сайт Flutter:flutter.dev/
Исходный код перемещен в Giuhub:GitHub.com/web1209/…
Картинкой делиться не буду, 23333.