前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Flutter 组件集录】 BackdropFilter | 8 月更文挑战md

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

作者头像
张风捷特烈
发布2022-03-18 15:51:08
8320
发布2022-03-18 15:51:08
举报
1.认识 BackdropFilter 组件

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

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

代码语言:javascript
复制
final ui.ImageFilter filter;
2.BackdropFilter 的使用

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

代码语言:javascript
复制
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 等裁剪组件进行裁剪,这样模糊层 就不会影响之外的部分。如下是圆角矩形的裁剪效果:

代码语言:javascript
复制
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

代码语言:javascript
复制
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
image-20210828154123795

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

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021/08/28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.认识 BackdropFilter 组件
  • 2.BackdropFilter 的使用
  • 3. 认识 ImageFilter
  • 4. BackdropFilter 组件的源码实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档