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

Flutter隐藏组件之Visibility 中, 我们介绍了关于 Visibility 的一些能力. 其中 maintainState 为 true 的时候会在 child 外添加一层 Offstage. Offstage 除了隐藏控件外, 还可以维护控件的 state. 本期我们就来分析一下 Offstage.

offstage

Offstage 是一个使用非常简单的组件, 它用于组件的隐藏. 当 offstage 为 true 时, child 不占用父空间, 也不绘制, 也不会被手势命中. 而为 false 时, 则一切正常.

1
2
3
4
5
6
7
8
Offstage(
offstage: true,
child: Container(
height: 100,
width: 100,
color: Colors.yellow,
),
)

它是一个继承于 SingleChildRenderObjectWidget 的组件, 也就是说实际上是对自身大小、绘制、布局作控制的自定义组件. 最终返回的是 RenderOffstage 对象.

1
2
@override
RenderOffstage createRenderObject(BuildContext context) => RenderOffstage(offstage: offstage);

RenderOffstage

在 RenderOffstage 中, 我们看到它在四个计算宽高的方法中, 如果 offstage 为 true 的时候, 统统都会返回 0.0, 否则会走原逻辑. 也就是说, 当我们改变了 offstage 属性的时候, 当前的 child 所需要约束是根据 offstage 属性来加载的.

image
在测量布局阶段, 如果 offstage 为 true , 那么在测量布局的时候 child layout 需要被更新的约束给约束. 由于我们已经将约束改到了最小, 所以实际上子 child 是没有空间去 layout 的.

2022121301.png
在绘制阶段, 如果 offstage 为 true , 最终的结果会直接 return. 也就是不会任何绘制出现. 当然也不会走到 child 的绘制流程. 所以整体画面都不会有东西呈现.

image
在点击命中判断时, 我们也可以看到在 hitTest 方法中, 如果 offstage 为true, 那么最终的结果会返回 false. 也就是说当前 child 是不会被记录命中的.

image


借助了布局、绘制、点击命中这三板斧, Offstage 实现了不占用父空间、不绘制也不接受点击命中测试, 但是本身却可以维护 state. 这也得益于 flutter 的三棵树结构. 可以最小成本的搭建组件.我们在自己开发时, 也可以参考这种设计. 可以做到隐藏但是接受点击事件. 类似于 app 开发中后门的操作.

结语

这里是WeninerIo😇

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

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

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

那就点个关注吧! ❤️

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