简介
咱们在应用 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