热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Flutter布局(五)LimitedBox、Offstage、OverflowBox、SizedBox详解

本文主要介绍Flutter布局中的LimitedBox、Offstage、OverflowBox、SizedBox四种控件,详细介绍了其布局行为以及使用场景,并对源

本文主要介绍Flutter布局中的LimitedBox、Offstage、OverflowBox、SizedBox四种控件,详细介绍了其布局行为以及使用场景,并对源码进行了分析。

1. LimitedBox

A box that limits its size only when it‘s unconstrained.

1.1 简介

LimitedBox,通过字面意思,也可以猜测出这个控件的作用,是限制类型的控件。这种类型的控件前面也介绍了不少了,这个是对最大宽高进行限制的控件。

1.2 布局行为

LimitedBox是将child限制在其设定的最大宽高中的,但是这个限定是有条件的。当LimitedBox最大宽度不受限制时,child的宽度就会受到这个最大宽度的限制,同理高度。

1.3 继承关系

Object > Diagnosticable > DiagnosticableTree > Widget > RenderObjectWidget > SingleChildRenderObjectWidget > LimitedBox

1.4 示例代码

Row(
  children: [
    Container(
      color: Colors.red,
      width: 100.0,
    ),
    LimitedBox(
      maxWidth: 150.0,
      child: Container(
        color: Colors.blue,
        width: 250.0,
      ),
    ),
  ],
)

1.5 源码解析

const LimitedBox({
  Key key,
  this.maxWidth = double.infinity,
  this.maxHeight = double.infinity,
  Widget child,
})

1.5.1 属性解析

maxWidth:限定的最大宽度,默认值是double.infinity,不能为负数。

maxHeight:同上。

1.5.2 源码

先不说其源码,单纯从其作用,前面介绍的SizedBox、ConstrainedBox都类似,都是通过强加到child的constraint,来达到相应的效果。

我们直接看其计算constraint的代码

minWidth: constraints.minWidth,
maxWidth: constraints.hasBoundedWidth ? constraints.maxWidth : constraints.constrainWidth(maxWidth),
minHeight: constraints.minHeight,
maxHeight: constraints.hasBoundedHeight ? constraints.maxHeight : constraints.constrainHeight(maxHeight)

LimitedBox只是改变最大宽高的限定。具体的布局代码如下:

if (child != null) {
  child.layout(_limitConstraints(constraints), parentUsesSize: true);
  size = constraints.constrain(child.size);
} else {
  size = _limitConstraints(constraints).constrain(Size.zero);
}

根据最大尺寸,限制child的布局,然后将自身调节到child的尺寸。

1.6 使用场景

使用场景是不可能清楚了,光是找例子,就花了不少时间。Flutter的一些冷门控件,真的是除了官方的文档,啥材料都木有。谷歌说这个很有用,还是一脸懵逼。这种控件,也有其他的替代解决方案,LimitedBox可以达到的效果,ConstrainedBox都可以实现。

2. Offstage

A widget that lays the child out as if it was in the tree, but without painting anything, without making the child available for hit testing, and without taking any room in the parent.

2.1 简介

Offstage的作用很简单,通过一个参数,来控制child是否显示,日常使用中也算是比较常用的控件。

2.2 布局行为

Offstage的布局行为完全取决于其offstage参数

  • 当offstage为true,当前控件不会被绘制在屏幕上,不会响应点击事件,也不会占用空间;
  • 当offstage为false,当前控件则跟平常用的控件一样渲染绘制;

另外,当Offstage不可见的时候,如果child有动画,应该手动停掉,Offstage并不会停掉动画。

2.3 继承关系

Object > Diagnosticable > DiagnosticableTree > Widget > RenderObjectWidget > SingleChildRenderObjectWidget > Offstage

2.4 示例代码

Column(
  children: [
    new Offstage(
      offstage: offstage,
      child: Container(color: Colors.blue, height: 100.0),
    ),
    new CupertinoButton(
      child: Text("点击切换显示"),
      onPressed: () {
        setState(() {
          offstage = !offstage;
        });
      },
    ),
  ],
)

当点击切换按钮的时候,可以看到Offstage显示消失。

2.5 源码解析

const Offstage({ Key key, this.offstage = true, Widget child })

2.5.1 属性解析

offstage:默认为true,也就是不显示,当为flase的时候,会显示该控件。

2.5.2 源码

我们先来看下Offstage的computeIntrinsicSize相关的方法:

@override
double computeMinIntrinsicWidth(double height) {
    if (offstage)
      return 0.0;
    return super.computeMinIntrinsicWidth(height);
  }

可以看到,当offstage为true的时候,自身的最小以及最大宽高都会被置为0.0。

接下来我们来看下其hitTest方法:

  @override
  bool hitTest(HitTestResult result, { Offset position }) {
    return !offstage && super.hitTest(result, position: position);
  }

当offstage为true的时候,也不会去执行。

最后我们来看下其paint方法:

@override
  void paint(PaintingContext context, Offset offset) {
    if (offstage)
      return;
    super.paint(context, offset);
  }

当offstage为true的时候直接返回,不绘制了。

到此,跟上面所说的布局行为对应上了。我们一定要清楚一件事情,Offstage并不是通过插入或者删除自己在widget tree中的节点,来达到显示以及隐藏的效果,而是通过设置自身尺寸、不响应hitTest以及不绘制,来达到展示与隐藏的效果。

2.6 使用场景

当我们需要控制一个区域显示或者隐藏的时候,可以使用这个场景。其实也有其他代替的方法,但是成本会高很多,例如直接在tree上插入删除,但是不建议这么做。

3. OverflowBox

A widget that imposes different constraints on its child than it gets from its parent, possibly allowing the child to overflow the parent.

3.1 简介

OverflowBox这个控件,允许child超出parent的范围显示,当然不用这个控件,也有很多种方式实现类似的效果。

3.2 布局行为

当OverflowBox的最大尺寸大于child的时候,child可以完整显示,当其小于child的时候,则以最大尺寸为基准,当然,这个尺寸都是可以突破父节点的。最后加上对齐方式,完成布局。

3.3 继承关系

Object > Diagnosticable > DiagnosticableTree > Widget > RenderObjectWidget > SingleChildRenderObjectWidget > OverflowBox

3.4 示例代码

Container(
  color: Colors.green,
  width: 200.0,
  height: 200.0,
  padding: const EdgeInsets.all(5.0),
  child: OverflowBox(
    alignment: Alignment.topLeft,
    maxWidth: 300.0,
    maxHeight: 500.0,
    child: Container(
      color: Color(0x33FF00FF),
      width: 400.0,
      height: 400.0,
    ),
  ),
)

技术分享图片

当maxHeight大于height的时候,可以完全显示下来,当maxHeight小于height的时候,则不会会被隐藏掉

3.5 源码解析

构造函数如下:

const OverflowBox({
    Key key,
    this.alignment = Alignment.center,
    this.minWidth,
    this.maxWidth,
    this.minHeight,
    this.maxHeight,
    Widget child,
  })

3.5.1 属性解析

alignment:对齐方式。

minWidth:允许child的最小宽度。如果child宽度小于这个值,则按照最小宽度进行显示。

maxWidth:允许child的最大宽度。如果child宽度大于这个值,则按照最大宽度进行展示。

minHeight:允许child的最小高度。如果child高度小于这个值,则按照最小高度进行显示。

maxHeight:允许child的最大高度。如果child高度大于这个值,则按照最大高度进行展示。

其中,最小以及最大宽高度,如果为null的时候,就取父节点的constraint代替。

3.5.2 源码

OverflowBox的源码很简单,我们先来看一下布局代码:

if (child != null) {
  child.layout(_getInnerConstraints(constraints), parentUsesSize: true);
  alignChild();
}

如果child不为null,child则会按照计算出的constraints进行尺寸的调整,然后对齐。

至于constraints的计算,则还是上面的逻辑,如果设置的有的话,就取这个值,如果没有的话,就拿父节点的。

3.6 使用场景

有时候设计图上出现的角标,会超出整个模块,可以使用OverflowBox控件。但我们应该知道,不使用这种控件,也可以完成布局,在最外面包一层,也能达到一样的效果。具体实施起来哪个比较方便,同学们自行取舍。

4. SizedBox

A box with a specified size.

4.1 简介

比较常用的一个控件,设置具体尺寸。

4.2 布局行为

SizedBox布局行为相对较简单:

  • child不为null时,如果设置了宽高,则会强制把child尺寸调到此宽高;如果没有设置宽高,则会根据child尺寸进行调整;
  • child为null时,如果设置了宽高,则自身尺寸调整到此宽高值,如果没设置,则尺寸为0;

4.3 继承关系

Diagnosticable > DiagnosticableTree > Widget > RenderObjectWidget > SingleChildRenderObjectWidget > SizedBox

4.4 示例代码

Container(
  color: Colors.green,
  padding: const EdgeInsets.all(5.0),
  child: SizedBox(
    width: 200.0,
    height: 200.0,
    child: Container(
      color: Colors.red,
      width: 100.0,
      height: 300.0,
    ),
  ),
)

4.5 源码解析

构造函数

const SizedBox({ Key key, this.width, this.height, Widget child })

4.5.1 属性解析

width:宽度值,如果具体设置了,则强制child宽度为此值,如果没设置,则根据child宽度调整自身宽度。

height:同上。

4.5.2 源码

SizedBox内部是通过RenderConstrainedBox来实现的。具体的源码就不解析了,总体思路是,根据宽高值算好一个constraints,然后强制应用到child上。

4.6 使用场景

这个控件,很多场景可以使用。但是,可以替代它的控件也有不少,例如Container、ConstrainedBox等。而且SizedBox就是ConstrainedBox的一个特例。还是那句话,精简啊,多提供一些常用的,不要提供一大堆重复的,场景很少的控件。

5. 后话

笔者建了一个Flutter学习相关的项目,Github地址,里面包含了笔者写的关于Flutter学习相关的一些文章,会定期更新,文章中的代码也在这个项目中,欢迎大家关注。

6. 参考

  1. LimitedBox class
  2. Offstage class
  3. OverflowBox class
  4. SizedBox class

Flutter 布局(五)- LimitedBox、Offstage、OverflowBox、SizedBox详解


推荐阅读
  • 第二十五天接口、多态
    1.java是面向对象的语言。设计模式:接口接口类是从java里衍生出来的,不是python原生支持的主要用于继承里多继承抽象类是python原生支持的主要用于继承里的单继承但是接 ... [详细]
  • 本指南详细介绍了如何利用华为云对象存储服务构建视频点播(VoD)平台。通过结合开源技术如Ceph、WordPress、PHP和Nginx,用户可以高效地实现数据存储、内容管理和网站搭建。主要内容涵盖华为云对象存储系统的配置步骤、性能优化及安全设置,为开发者提供全面的技术支持。 ... [详细]
  • Vim 编辑器功能强大,但其默认的配色方案往往不尽如人意,尤其是注释颜色为蓝色时,对眼睛极为不友好。为了提升编程体验,自定义配色方案显得尤为重要。通过合理调整颜色,不仅可以减轻视觉疲劳,还能显著提高编码效率和兴趣。 ... [详细]
  • 本文详细介绍了如何解决DNS服务器配置转发无法解析的问题,包括编辑主配置文件和重启域名服务的具体步骤。 ... [详细]
  • CentOS 7 中 iptables 过滤表实例与 NAT 表应用详解
    在 CentOS 7 系统中,iptables 的过滤表和 NAT 表具有重要的应用价值。本文通过具体实例详细介绍了如何配置 iptables 的过滤表,包括编写脚本文件 `/usr/local/sbin/iptables.sh`,并使用 `iptables -F` 清空现有规则。此外,还深入探讨了 NAT 表的配置方法,帮助读者更好地理解和应用这些网络防火墙技术。 ... [详细]
  • 在 LeetCode 的“有效回文串 II”问题中,给定一个非空字符串 `s`,允许删除最多一个字符。本篇深入解析了如何判断删除一个字符后,字符串是否能成为回文串,并提出了高效的优化算法。通过详细的分析和代码实现,本文提供了多种解决方案,帮助读者更好地理解和应用这一算法。 ... [详细]
  • 系统数据实体验证异常:多个实体验证失败的错误处理与分析
    在使用MVC和EF框架进行数据保存时,遇到了 `System.Data.Entity.Validation.DbEntityValidationException` 错误,表明存在一个或多个实体验证失败的情况。本文详细分析了该错误的成因,并提出了有效的处理方法,包括检查实体属性的约束条件、调试日志的使用以及优化数据验证逻辑,以确保数据的一致性和完整性。 ... [详细]
  • MySQL的查询执行流程涉及多个关键组件,包括连接器、查询缓存、分析器和优化器。在服务层,连接器负责建立与客户端的连接,查询缓存用于存储和检索常用查询结果,以提高性能。分析器则解析SQL语句,生成语法树,而优化器负责选择最优的查询执行计划。这一流程确保了MySQL能够高效地处理各种复杂的查询请求。 ... [详细]
  • 装饰者模式(Decorator):一种灵活的对象结构设计模式
    装饰者模式(Decorator)是一种灵活的对象结构设计模式,旨在为单个对象动态地添加功能,而无需修改原有类的结构。通过封装对象并提供额外的行为,装饰者模式比传统的继承方式更加灵活和可扩展。例如,可以在运行时为特定对象添加边框或滚动条等特性,而不会影响其他对象。这种模式特别适用于需要在不同情况下动态组合功能的场景。 ... [详细]
  • 本项目通过Python编程实现了一个简单的汇率转换器v1.02。主要内容包括:1. Python的基本语法元素:(1)缩进:用于表示代码的层次结构,是Python中定义程序框架的唯一方式;(2)注释:提供开发者说明信息,不参与实际运行,通常每个代码块添加一个注释;(3)常量和变量:用于存储和操作数据,是程序执行过程中的重要组成部分。此外,项目还涉及了函数定义、用户输入处理和异常捕获等高级特性,以确保程序的健壮性和易用性。 ... [详细]
  • 本文详细解析了Autofac在高级应用场景中的具体实现,特别是如何通过注册泛型接口的类来优化依赖注入。示例代码展示了如何使用 `builder.RegisterAssemblyTypes` 方法,结合 `typeof(IEventHandler).Assembly` 和 `Where` 过滤条件,动态注册所有符合条件的类,从而简化配置并提高代码的可维护性。此外,文章还探讨了这一方法在复杂系统中的实际应用及其优势。 ... [详细]
  • VS2019 在创建 Windows 恢复点时出现卡顿问题及解决方法
    在使用 Visual Studio 2019 时,有时会在创建 Windows 恢复点时遇到卡顿问题。这可能是由于频繁的自动更新导致的,每次更新文件大小可能达到 1-2GB。尽管现代网络速度较快,但这些更新仍可能对系统性能产生影响。本文将探讨该问题的原因,并提供有效的解决方法,帮助用户提升开发效率。 ... [详细]
  • 为了提升单位内部沟通效率,我们开发了一套飞秋软件与OA系统的消息接口服务系统。该系统能够将OA系统中的审批、通知等信息自动同步至飞秋平台,确保员工在使用飞秋进行日常沟通的同时,也能及时获取OA系统的各类重要信息,从而实现无缝对接,提高工作效率。 ... [详细]
  • 浏览器作为我们日常不可或缺的软件工具,其背后的运作机制却鲜为人知。本文将深入探讨浏览器内核及其版本的演变历程,帮助读者更好地理解这一关键技术组件,揭示其内部运作的奥秘。 ... [详细]
  • 深入解析:Synchronized 关键字在 Java 中对 int 和 Integer 对象的作用与影响
    深入探讨了 `Synchronized` 关键字在 Java 中对 `int` 和 `Integer` 对象的影响。尽管初看此题似乎简单,但其实质在于理解对象的概念。根据《Java编程思想》第二章的观点,一切皆为对象。本文详细分析了 `Synchronized` 关键字在不同数据类型上的作用机制,特别是对基本数据类型 `int` 和包装类 `Integer` 的区别处理,帮助读者深入理解 Java 中的同步机制及其在多线程环境中的应用。 ... [详细]
author-avatar
万世一统_425
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有