flutter 系列之:flutter 中的幽灵offstage
简介
我们在使用flutter的过程中,有时候需要控制某些组件是否展示,一种方法是将这个组件从render tree中删除,这样这个组件就相当于没有出现一样,但是有时候,我们只是不想展示这个widget,但是这个组件还是存在的,并且可以接受键盘输入,还可以使用CPU。它和真正的组件唯一不同的就是他是不可见的。
这样的组件就叫做Offstage。 今天给大家详细介绍一下Offstage的使用。
Offstage详解
我们首先来看下Offstage的定义:
class Offstage extends SingleChildRenderObjectWidget
可以看到,Offstage是一个包含单个child的Widget。接下来看下它的构造函数:
const Offstage({ Key? key, this.offstage = true, Widget? child })
: assert(offstage != null),
super(key: key, child: child);
Offstage主要包含两个属性,分别是表示是否是offstage状态的bool值offstage,如果offstage=true,那么Offstage的子child就会处于隐藏状态。这时候子child不会占用任何空间。
剩下的一个属性就是child了。
那么Offstage是如何控制child是否offstage的呢?
我们看下它的createRenderObject方法:
RenderOffstage createRenderObject(BuildContext context) => RenderOffstage(offstage: offstage);
可以看到返回的是一个RenderOffstage对象,其中接受一个offstage参数。
如果深入研究RenderOffstage的话,可以看到他的paint方法是这样的:
void paint(PaintingContext context, Offset offset) {
if (offstage)
return;
super.paint(context, offset);
}
如果offstage是true的话,paint方法直接返回,不会进行任何的绘制。这也就是Offstage的秘密。
Offstage的使用
从上面讲解的Offstage的构造函数我们知道,Offstage需要一个bool的offstage属性。所以这个offstage属性是可以变换的,从而触发offstage的不同状态。
因为offstage需要这样的一个状态,所以我们在使用offstage的时候,一般来说是创建一个StatefulWidget,从而在StatefulWidget中保持这样的一个offstage属性。
比如我们创建一个OffstageApp,这是一个StatefulWidget,在它的createState方法中,返回一个State<OffstageApp>对象,在createState方法中,我们定义一个_offstage属性。
通过使用这个_offstage,我们可以创建Offstage如下:
Offstage(
offstage: _offstage,
child: SizedBox(
key: _key,
width: 150.0,
height: 150.0,
child: Container(
color: Colors.red,
),
),
)
这里我们设置Offstage的offstage为刚刚设置的_offstage。
另外为了展示方便,我们将Offstage的child设置为一个SizedBox,里面包含了一个红色的Container。
SizedBox包含了width和height属性,方便我们后续的测试。
默认情况下,因为_offstage=true,所以这个Offstage是不可见的,那么怎么将其可见呢?
我们提供一个ElevatedButton,在它的onPressed方法中,我们调用setState方法来修改_offstage,如下所示:
ElevatedButton(
child: const Text('切换offstage'),
onPressed: () {
setState(() {
_offstage = !_offstage;
});
},
),
另外,我们还需要一个ElevatedButton来检测Offstage的大小,看看在_offstage发生变化的时候,Offstage到底会不会发生变化。
ElevatedButton(
child: const Text('检测SizedBox大小'),
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content:
Text('SizedBox is ${_getSizedBoxSize()}'),
),
);
})
这里的_getSizedBoxSize实现如下:
Size _getSizedBoxSize() {
final RenderBox renderBox =
_key.currentContext!.findRenderObject()! as RenderBox;
return renderBox.size;
}
我们通过Offstage的_key,来获取到它的Context,从而找到对应的RenderBox,拿到它的大小。
好了,这样我们的代码就写好了,最后将OffstageApp放到Scaffold中运行,我们可以得到下面的界面:

默认Offstage是不会展示的。
如果我们点击下面的检测SizeBox大小的按钮,可以得到下面的界面:

可以看到虽然Offstage没有展示,但是还是获取到了它的大小。
然后我们点击切换Offstage按钮,可以得到下面的界面:

界面完美的展示了。
总结
Offstage是一个非常方便的组件,可以用来隐藏我们不需要展示的组件,但是仍然可以获得它的大小。
本文的例子:https://github.com/ddean2009/learn-flutter.git
flutter 系列之:flutter 中的幽灵offstage的更多相关文章
- flutter系列之:flutter架构什么的,看完这篇文章就全懂了
目录 简介 Flutter的架构图 embedder engine Flutter framework Widgets Widgets的可扩展性 Widgets的状态管理 渲染和布局 总结 简介 Fl ...
- flutter系列之:flutter中常用的container layout详解
目录 简介 Container的使用 旋转Container Container中的BoxConstraints 总结 简介 在上一篇文章中,我们列举了flutter中的所有layout类,并且详细介 ...
- flutter系列之:flutter中常用的Stack layout详解
[toc] 简介 对于现代APP的应用来说,为了更加美观,通常会需要用到不同图像的堆叠效果,比如在一个APP用户背景头像上面添加一个按钮,表示可以修改用户信息等. 要实现这样的效果,我们需要在一个Im ...
- flutter系列之:Material中的3D组件Card
目录 简介 Card详解 Card的使用 总结 简介 除了通用的组件之外,flutter还提供了两种风格的特殊组件,其中在Material风格中,有一个Card组件,可以很方便的绘制出卡片风格的界面, ...
- flutter系列之:flutter中可以建索引的栈布局IndexedStack
目录 简介 IndexedStack简介 IndexedStack的使用 总结 简介 之前我们介绍了一个flutter的栈结构的layout组件叫做Stack,通过Stack我们可以将一些widget ...
- flutter系列之:flutter中常用的GridView layout详解
目录 简介 GridView详解 GridView的构造函数 GridView的使用 总结 简介 GridView是一个网格化的布局,如果在填充的过程中子组件超出了展示的范围的时候,那么GridVie ...
- flutter系列之:flutter中常用的ListView layout详解
目录 简介 ListView详解 ListView中的特有属性 ListView的构造函数 ListView的使用 总结 简介 ListView是包含多个child组件的widget,在ListVie ...
- Flutter系列博文链接
Flutter系列博文链接 ↓: Flutter基础篇: Flutter基础篇(1)-- 跨平台开发框架和工具集锦 Flutter基础篇(2)-- 老司机用一篇博客带你快速熟悉Dart语法 Flutt ...
- flutter系列之:用来管理复杂状态的State详解
目录 简介 StatefuWidget和State State的生命周期 总结 简介 Flutter的基础是widget,根据是否需要跟用户进行交互,widget则可以分为StatelessWidge ...
随机推荐
- [HFCTF2020]EasyLogin-1|JWT身份伪造
1.打开之后只有一个登陆界面和注册界面,右键检查发现app.js代码,结果如下: app.js代码如下: /** * 或许该用 koa-static 来处理静态文件 * 路径该怎么配置?不管了先填个根 ...
- virtio_net 设备的队列数问题
virtio_net设备的其他问题:见 https://www.cnblogs.com/10087622blog/p/15886345.html 一个virtio_net设备在 virtnet_pro ...
- ipi发送阻塞导致crash
3.10的内核, 在子进程退出的时候,发送信号通知父进程,此时是持有父进程的sighand中的spinlock的,然后父进程和该子进程不在一个核上,发送ipi的reschedule中断给对应的核, 但 ...
- 基于SpringSecurity的@PreAuthorize实现自定义权限校验方法
一.前言 在我们一般的web系统中必不可少的就是权限的配置,也有经典的RBAC权限模型,是基于角色的权限控制.这是目前最常被开发者使用也是相对易用.通用权限模型.当然SpringSecurity已经实 ...
- 第一百篇:JS异步
好家伙,打工人要打工,博客会更新的没有以前频繁了 芜湖,一百篇了,这篇写一个比较难的异步(其实并不难理解,主要是为promise铺垫) 老样子,先补点基础: 1.进程 来吧,新华字典 大 ...
- 移动教室APP
软件名:VERIMAG 官网链接:http://www.verimag.ru/mobilnoe-obrazovanie.html 移动课堂,充满活力的气息.走在时代前沿的同时,也对教育者对于编制课件的 ...
- 搭建eBackup对接NFS服务
环境准备 两个虚拟机需要是仅主机并且同一网段 先搭建一个eBackup环境虚拟机 搭建步骤可访问:(https://www.cnblogs.com/zhengyan6/p/16220774.html) ...
- pat乙级每日习题
欢迎加入我们:qq群:1054587486 1:https://pintia.cn/problem-sets/994805260223102976/problems/99480532591848652 ...
- Spring配置XML本地提示
Spring配置XML本地提示:点击eclipse属性-->选择XML Catalog 这里有一点要注意:要选择schema location
- flink-cdc同步mysql数据到hbase
本文首发于我的个人博客网站 等待下一个秋-Flink 什么是CDC? CDC是(Change Data Capture 变更数据获取)的简称.核心思想是,监测并捕获数据库的变动(包括数据 或 数据表的 ...