前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Flutter 组件集录】Visibility| 8月更文挑战

【Flutter 组件集录】Visibility| 8月更文挑战

作者头像
张风捷特烈
发布2022-03-18 15:38:03
1.8K0
发布2022-03-18 15:38:03
举报
一、认识 Visibility 组件

前面介绍了 Offstage 组件可以控制 child显隐,与它相比较的往往是 Visibility 组件。Offstage 源码中有对 Visibility 的一句介绍:它可以更高效地隐藏组件(尽管不那么微妙)。

现在仔细想想,OpacityOffstageVisibility 都可以控制组件的显示/隐藏 。那它们之间有什么样的区别和联系呢?通过本文,我将从 Visibility 源码中为你揭晓答案。

1.Visibility 基本信息

下面是 Visibility 组件类的定义构造方法,可以看出它继承自 StatelessWidget。实例化时必须传入 child 组件,另外还有一堆选填的 bool 属性和一个 replacement 组件。

2.Visibility 的简单使用

下面是 Visibility 组件的默认效果,中间的图标是待显隐组件,通过点击按钮切换现有状态。可以看出,直接使用 Visibility 时,组件隐藏时不会占位

代码语言:javascript
复制
class OffstageDemo extends StatefulWidget {
  @override
  _OffstageDemoState createState() => _OffstageDemoState();
}

class _OffstageDemoState extends State<OffstageDemo> {
  bool _visible = true;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        ElevatedButton(
          child: const Text('切换显隐'),
          onPressed: _toggleVisible,
        ),
        Visibility(
          visible: _visible,
          child: buildChild(),
        ),
        Text('默认情况'),
      ],
    );
  }

  void _toggleVisible() {
    setState(() {
      _visible = !_visible;
    });
  }

  Widget buildChild() => const Padding(
        padding: const EdgeInsets.all(10),
        child: Icon(
          Icons.camera_outlined,
          color: Colors.green,
          size: 50,
        ),
      );
}
3.Visibility 的占位组件

Visibility 中有一个 replacement 的可选属性,类型是 Widget ,用于占位。

代码语言:javascript
复制
this.replacement = const SizedBox.shrink(),

final Widget replacement;

默认 replacementSizedBox.shrink() ,即宽高为 0SizedBox

我们可以通过 Flutter Inspector 查看树的详细信息,可以看出在隐藏时。渲染树中确实有通过 SizedBox 对象的渲染对象节点,且宽高为 0 。

下面是设置 replacement 的效果,可以看出在隐藏时,会显示 replacement 对应的组件。

代码语言:javascript
复制
Visibility(
  visible: _visible,
  child: buildChild(),
  replacement: buildPlaceholder(),
),

Widget buildPlaceholder() => Container(
      width: 50,
      height: 50,
      padding: const EdgeInsets.all(10),
      child: Placeholder(),
    );
4. 五个 maintainXXX

下面就剩下来五个 maintainXXX 的布尔属性。

我们先来看一下,构造中的断言处理:

先看一下 maintainSize ,表示隐藏时是否保持尺寸。默认为 false 。通过断言 2 可以看出:

代码语言:javascript
复制
maintainSize: true 时,必须 maintainAnimation: true ,否则断言失败。

通过断言 1 可以看出:

代码语言:javascript
复制
maintainAnimation: true 时,必须 maintainState: true ,否则断言失败。

也就是说,如果想要保持尺寸,必须 maintainAnimationmaintainState 。如下是 maintainSize 的效果,这样隐藏时,原尺寸区域不会消失。

代码语言:javascript
复制
Visibility(
  visible: _visible,
  child: buildChild(),
  maintainSize: true,
  maintainAnimation: true,
  maintainState: true,
),

看一下结构,有一个透明度为 0Opacity 组件,看懂的应该能会心一笑。

maintainInteractivity 的作用也非常简单,它可以控制在隐藏时是否响应事件。

另外 maintainAnimationmaintainState 作用是什么,就让源码来告诉你吧。

二、 Visibility 的源码实现
1. 尺寸和点击事件的保持

Visibility 组件作为一个 StatelessWidget,就决定它本身并不掌握"核心科技" ,只是在 build 方法中组合使用其他组件而已。在源码 build 方法中,可以看出:

如果 maintainSizetrue ,会通过 Opacity 组件进行包裹,根据 visible 控制透明度。 maintainInteractivityfalse , 会通过 IgnorePointer 组件进行包裹,忽略点击事件。

2. 保持状态和动画

如果 maintainStatetrue ,会通过 Offstage 组件进行包裹,根据 visible 控制是否显示,对于 Offstage 组件介绍,详见此文。如果 maintainAnimationfalse , 会通过 TickerMode 组件进行包裹,在隐藏时禁用子组件动画。 TickerMode 组件介绍,详见此文

3.为什么说 Visibility 是高效的?

如果五个 maintainXXX 是默认情况,那么 Visibility 组件直接通过 visible 属性决定返回组件,不需要通过 OpacityOffstage组件完成显隐功能。 另外,maintainStatemaintainAnimation 必须同时为 true ,这也能给使用者一个保障,避免使用 Offstage 是忘记子组件禁止动画。

到这里可以看出,Visibility 组件 可以说是显隐功能的合集。能控制四个属性:是否接受事件是否保持尺寸是否保持状态是否停止动画,分别由 IgnorePointerOpacityOffstageTickerMode 实现。是一个上层的简单封装,目的是方便用户使用,尽可能少犯错误。所以如果想显隐组件,又不知道用什么好,Visibility 可以无脑翻牌。

Visibility 的使用方式到这里就介绍完毕,那本文到这里就结束了,谢谢观看,明天见~

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021/08/13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、认识 Visibility 组件
  • 1.Visibility 基本信息
  • 2.Visibility 的简单使用
  • 3.Visibility 的占位组件
  • 4. 五个 maintainXXX
  • 二、 Visibility 的源码实现
    • 1. 尺寸和点击事件的保持
      • 2. 保持状态和动画
        • 3.为什么说 Visibility 是高效的?
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档