关于flutter:flutter-系列之flutter-中的幽灵offstage

40次阅读

共计 2475 个字符,预计需要花费 7 分钟才能阅读完成。

简介

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

正文完
 0