【Flutter 组件集录】 BackdropFilter | 8 月更文挑战md
前言:
1.认识 BackdropFilter 组件
BackdropFilter
组件可能很少人使用,但它的功能还是很强大的。源码中对它的介绍是:对已有的绘制内容添加一个过滤器,然后再绘制它的孩子。
下面是 BackdropFilter
组件类的定义
和 构造方法
,可以看出它继承自 SingleChildRenderObjectWidget
。构造时必须传入尺寸 filter
参数,其类型是 ImageFilter
。
final ui.ImageFilter filter;
2.BackdropFilter 的使用
源码中有一个 BackdropFilter
组件的测试案例,我们先基于这个案例,看一下 BackdropFilter
的效果及作用。下图中,有三个区域: 01文字
、紫色区域
、Hello World
文字。实现的方式是:通过 Stack
叠合 01文字
和 BackdropFilter
,其中紫色区域和Hello World
文字是 BackdropFilter
的子组件。
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
等裁剪组件进行裁剪,这样模糊层
就不会影响之外的部分。如下是圆角矩形的裁剪效果:
ClipRRect(
borderRadius: BorderRadius.circular(20),
child: buildFilterZone(),
),
3. 认识 ImageFilter
首先 ImageFilter
是一个抽象类,但它可以通过命名构造创建对象,如下有三种构造方式。
拿 ImageFilter.blur
来说,可以看到构造前面有一个 factory
关键字,以此让抽象类也可以创建对象。可以看出这个构造本质上是使用了 _GaussianBlurImageFilter
,也就是高斯模糊
。两个入参 sigmaX
和 sigmaY
是模糊的程度。
比如下面是 x:2.0,y:2.0
的效果:
这是 x:4.0,y:1.0
的效果:
这是 x:6.0,y:6.0
的效果:
可见 sigmaX
和 sigmaY
分别控制 X
和 Y
方向上的模糊程度。
除了通过 ImageFilter.blur
创建 模糊遮罩
,还可以通过 ImageFilter.matrix
对区域内进行矩阵变换,如下面的 skewX
。
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
渲染对象来实现添加滤色器功能。
在 RenderBackdropFilter#paint
中创建 BackdropFilterLayer
对象 layer
,并将传入的 filter
设置给 layer
。通过 context.pushLayer
添加一个层,实现滤色器功能。
那本文到这里就结束了,谢谢观看,明天见~
转载自:https://juejin.cn/post/7001394814285512717