本系列教程基于Flutter widget, 意在为Flutter 入门提供基础建设. 重点在讲解widget 的 用法,参数以及扩展.
适宜人群: 入门

Flutter隐藏组件之VisibilityFlutter 组件分析之Opacity 中, 我们介绍了两种 Flutter 隐藏组件的方式, 实际上我们也可以通过 Opacity 来隐藏 widget. 它是一种可以控制组件透明度的方式来控制组件的展示. 以下我们来分一下 Opactiy .

Opactiy

Opacity 可以对任意的 child 作透明度变化, 因此它也可以隐藏或者显示 child. 它的构成很简单:

image
主要是通过参数 opacity 控制 child 的透明度效果. alwaysIncludeSemantics 则是与语义相关, 也就是无论 child 是否透明, 都会拥有该语义. 我们的重点也就是在 opacity 上. 这里通过一个示例:

image
图左是原图 , 图右是 opacity = 0.5 时的效果. 如果我们通过 Stack 布局, 将 Image 置于上层 , 将一个 100*100 的色块置于下层. 那么最终效果如下图:

1
2
3
4
5
6
7
8
9
10
11
12
13
Stack(
alignment: Alignment.center,
children: [
Container(
height: 100,
width: 100,
color: Colors.blue,
),
Opacity(
opacity: 0.5,
child: Image.network('xx'),
)],
)

如图:

image
我们可以清楚看到, 一个蓝色的色块正置于图像的背后. 所以 opacity 会影响图层的绘制.

原理

Opacity 通过 createRenderObject 生成了 RenderOpacity 对象. 这里可以看到 Opacity 主要修改了 paint 方法. 我们也聚焦看看在 paint 中到底做了哪些操作叭 ?

paint

在 Paint 方法中, 如果当前的透明度为 0, 为了性能考虑 . 是不会调用绘制的方法的. 当透明度非0时, 通过 PaintingContext 的 pushOpacity 方法. 将进一步绘制与透明通道的值混合.

image

pushOpacity

在 pushOpacity 的方法中, 首先创建了一个 OpacityLayer 的 layer 对象, 它是继承于 OffsetLayer 的. 它主要用于将child 透明的合成层. 最终会通过 pushLayer 的方法将当前图层加入到需要展示的图层中.

image

OpacityLayer

我们会在 OpacityLayer 中最终透明化当前的图层. 这里主要在 addToScene 的方法中, 我们可以看到当传入的 opactiy 小于 1 时所走的分支, 这里会生成一个 OpacityEngineLayer .

image
我们通过 builder.pushOpacity 方法中调用了native 的 SceneBuilder_pushOpacity

image


通过这一系列的转换, 最后图层会透明化. 实际上最终的实现还是会通过skia_engine. 当透明度为 0 时不会 paint, 当透明度为 1 时,会最终走进 ui.SceneBuilder.pushOffset 合成图层.

结语

这里是WeninerIo😇

如果你对这次的技术分享感兴趣或者有什么疑惑🧐

不妨在评论区留言或私信🤪

或许这次的分享不是你所期待的😣

那就点个关注吧! ❤️

下次也许就是你想看的呢🫣?