简介

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