Android Flutter中Offstage组件的使用教程详解

作者:程序那些事 时间:2023-08-20 01:01:44 

简介

我们在使用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,拿到它的大小。

来源:https://juejin.cn/post/7113908125278666789

标签:Android,Flutter,Offstage
0
投稿

猜你喜欢

  • mybatis中foreach嵌套if标签方式

    2023-11-20 23:11:05
  • Java日常练习题,每天进步一点点(10)

    2022-08-11 21:55:53
  • Kotlin中常见内联扩展函数的使用方法教程

    2023-07-04 13:46:12
  • java实现滑动验证解锁

    2023-06-02 12:16:36
  • 六款值得推荐的android(安卓)开源框架简介

    2023-06-24 01:46:54
  • C# 通过 oledb 操作Excel实例代码

    2022-12-22 04:27:49
  • Java编程实现判断网上邻居文件是否存在的方法

    2022-12-27 09:49:46
  • C#设计模式之Singleton模式

    2022-03-28 09:01:31
  • C#在子线程中更新窗口部件的写法

    2022-04-01 09:57:50
  • 解决C#调用dll提示

    2022-11-30 21:46:39
  • 2021年最新Redis面试题汇总(3)

    2022-02-27 13:31:22
  • Mapper类中存在名称相同的方法重载报错问题

    2023-04-04 02:44:39
  • Spring Boot示例分析讲解自动化装配机制核心注解

    2022-07-26 15:56:14
  • c#只读字段和常量的区别,以及静态构造函数的使用实例

    2023-10-31 09:52:20
  • 说说@ModelAttribute在父类和子类中的执行顺序

    2022-07-31 17:59:55
  • Java 使用Socket正确读取数据姿势

    2023-09-16 12:13:43
  • Android如何获取系统通知的开启状态详解

    2021-12-28 05:45:09
  • 详解Spring Bean 之间的特殊关系

    2022-10-25 21:12:17
  • Java Socket实现传输压缩对象的方法示例

    2022-12-18 06:52:30
  • Java原子操作CAS原理解析

    2021-10-20 01:07:05
  • asp之家 软件编程 m.aspxhome.com