【Flutter 组件集录】 BackdropFilter | 8 月更文挑战md

前言:

这是我参与8月更文挑战的第 28 天,活动详情查看:8月更文挑战。为应掘金的八月更文挑战,我准备在本月挑选 31 个以前没有介绍过的组件,进行全面分析和属性介绍。这些文章将来会作为 Flutter 组件集录 的重要素材。希望可以坚持下去,你的支持将是我最大的动力~

| 本系列 | 组件文章 | 列表 | | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | | 1.NotificationListener | 2.Dismissible | 3.Switch | | 4.Scrollbar | 5.ClipPath | 6.CupertinoActivityIndicator | | 7.Opacity | 8.FadeTransition | 9. AnimatedOpacity | | 10. FadeInImage | 11. Offstage | 12. TickerMode | | 13. Visibility | 14. Padding | 15. AnimatedContainer | | 16.CircleAvatar | 17.PhysicalShape | 18.Divider | | 19.Flexible、Expanded 和 Spacer | 20.Card | 21.SizedBox | | 22.ConstrainedBox | 23.Stack | 24.Positioned | | 25.OverflowBox | 26.SizedOverflowBox | 27. DecoratedBox | | 28. BackdropFilter | | |


1.认识 BackdropFilter 组件

BackdropFilter 组件可能很少人使用,但它的功能还是很强大的。源码中对它的介绍是:对已有的绘制内容添加一个过滤器,然后再绘制它的孩子。


下面是 BackdropFilter 组件类的定义构造方法,可以看出它继承自 SingleChildRenderObjectWidget 。构造时必须传入尺寸 filter 参数,其类型是 ImageFilter

dart final ui.ImageFilter filter;


2.BackdropFilter 的使用

源码中有一个 BackdropFilter 组件的测试案例,我们先基于这个案例,看一下 BackdropFilter 的效果及作用。下图中,有三个区域: 01文字紫色区域Hello World 文字。实现的方式是:通过 Stack 叠合 01文字BackdropFilter ,其中紫色区域和Hello World 文字是 BackdropFilter 的子组件。

```dart class CustomBackdropFilter extends StatelessWidget { final Random random = Random();

@override Widget build(BuildContext context) { String data = ''; for (int i = 0; i < 10000; i++) { data += random.nextBool() ? " 0 " : " 1 "; }

return Stack(
  children: <Widget>[
    Text(data),
    Center(child: buildFilterZone(),),
  ],
);

}

Widget buildFilterZone() { return BackdropFilter( filter: ui.ImageFilter.blur( sigmaX: 2.0, sigmaY: 2.0, ), child: Container( alignment: Alignment.center, width: 200.0, height: 120.0, color: Colors.purple.withOpacity(0.1), child: const Text( 'Hello World', style: TextStyle(fontSize: 24), ), ), ); } } ```

从布局查看器中可以看出:BackdropFilter 的区域只是紫色部分,模糊遮罩并不会对其子组件产生影响。就像是在组件上层覆盖一个模糊层,而是子组件会在模糊层之上。


有时我们可能只是对某个区域进行遮罩处理,可以通过 ClipRRect 等裁剪组件进行裁剪,这样模糊层 就不会影响之外的部分。如下是圆角矩形的裁剪效果:

dart ClipRRect( borderRadius: BorderRadius.circular(20), child: buildFilterZone(), ),


3. 认识 ImageFilter

首先 ImageFilter 是一个抽象类,但它可以通过命名构造创建对象,如下有三种构造方式。

ImageFilter.blur 来说,可以看到构造前面有一个 factory 关键字,以此让抽象类也可以创建对象。可以看出这个构造本质上是使用了 _GaussianBlurImageFilter ,也就是高斯模糊。两个入参 sigmaXsigmaY 是模糊的程度。


比如下面是 x:2.0,y:2.0 的效果:

这是 x:4.0,y:1.0 的效果:

这是 x:6.0,y:6.0 的效果:

可见 sigmaXsigmaY 分别控制 XY 方向上的模糊程度。


除了通过 ImageFilter.blur 创建 模糊遮罩,还可以通过 ImageFilter.matrix 对区域内进行矩阵变换,如下面的 skewX

dart Widget buildFilterZone() { return BackdropFilter( filter: ui.ImageFilter.matrix(Matrix4.skewX(45/180*pi).storage), child: Container( alignment: Alignment.center, width: 200.0, height: 120.0, color: Colors.blueAccent.withOpacity(0.1), child: const Text( 'Hello World', style: TextStyle(fontSize: 24), ), ), ); }


4. BackdropFilter 组件的源码实现

BackdropFilter 继承自 SingleChildRenderObjectWidget ,内部维护 RenderBackdropFilter 渲染对象来实现添加滤色器功能。

image-20210828154123795


RenderBackdropFilter#paint 中创建 BackdropFilterLayer 对象 layer,并将传入的 filter 设置给 layer 。通过 context.pushLayer 添加一个层,实现滤色器功能。

那本文到这里就结束了,谢谢观看,明天见~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值