布局约束

基本规则

  • 首先,上层 widget 向下层 widget 传递约束条件
  • 然后,下层 widget 向上层 widget 传递大小信息
  • 最后,上层 widget 决定下层 widget 的位置

细节描述

  • 首先,widget 会通过它的父级获得自身的约束。约束为 4 个浮点类型的集合:最大、最小宽度,最大、最小高度
  • 然后,这个 widget 会逐个遍历它的子级,向每个子级传递约束(子级之间的约束可能会不同),然后询问每个子级需要用于布局的大小
  • 然后,这个 widget 会对它的每个子级逐个进行布局
  • 最后,这个 widget 把它的大小信息传递给父级,包括其自身的原始约束条件

限制

  • 一个 widget 仅在其父级给其约束的情况下才能决定自身的大小。这意味着 widget 通常情况下不能任意获得其想要的大小
  • 一个 widget 无法知道,也不需要决定其在屏幕中的位置。因为它的位置是由其父级决定的
  • 当轮到父级决定其大小和位置的时候,同样也取决于它自身的父级。所以在不考虑整棵树的情况下,几乎不可能精确定义任何 widget 的大小和位置
  • 如果子级想要拥有和父级不同的大小,然后父级没有足够的空间对其进行布局的话,子级的设置的大小可能不会生效。此时请明确指定它的对齐方式

Container

Container 的表现

  • 以屏幕为父级,屏幕强制 Container 变成和屏幕一样大小,无论 Container 的参数如何设置
  • Center 为父级,此时 Center 变成全屏,Center 告诉 Container 可以渲染成任意大小,但是不能超出屏幕,此时 Container 将根据其自身的参数渲染
    • Container 的宽高为无限时,将变成和屏幕一样大小
    • Container 没有参数时,将变成和屏幕一样大小(这个决定是由其父级决定的,可能会因父级的不同而不同,须阅读 Container 的文档来理解不同常见下它的这种行为)
    • Container 具有 padding 参数时,padding 将被带入约束的计算中
  • Align 为父级,效果与 Center 一样,不同的是 Align 默认不会剧中,且可以通过 alignment 参数调整位置
  • ConstrainedBox 为父级,因为 ConstrainedBox 仅对其从其父级接收到的约束下施加其他约束,此时屏幕告诉 ConstrainedBox 为全屏,因此它告诉 Container 也以屏幕大小为约束,从而忽略自身的其他参数。当 ConstrainedBox 被其他元素包裹时,它自身的参数将会生效,此时 Container 将被限制在 ConstrainedBox 的最大最小参数值的范围内
  • UnconstrainedBox 为父级,UnconstrainedBox 允许其子级变为任意大小,因此 Container 可以变为任意大小
    • Container 超出 UnconstrainedBox 时,将会显示溢出警告
    • Container 宽高为无限时,控制台将报错
    • ContainerLimitedBox 包裹时,Container 的无限宽高将被忽略,被强制限制为 LimitedBox 的宽高
    • LimitedBox 的限制参数,仅在获得无限约束时才适用,这是它与 ConstrainedBox 的区别
  • OverflowBox 为父级,OverflowBoxUnconstrainedBox 类似,区别在于子级超出时不会显示溢出警告

FittedBox

FittedBox 的表现(以 Text 为子级说明)

  • 以屏幕为父级,屏幕会让 FittedBox 强制全屏,因此 FittedBox 会强制缩放 Text,使其占满屏幕空间
  • Center 为父级,此时 CenterFittedBox 可以变为任意大小,FittedBox 将会根据 Text 的尺寸调整自己的大小
    • Text 尺寸小于或等于屏幕大小时,不会发生缩放
    • Text 尺寸大于屏幕时,由于 FittedBox 的大小限制为屏幕大小,此时将会对 Text 进行缩放以适应屏幕
  • FittedBox 的子级的宽高为无限时,控制台会报错

Row

Row 的表现

  • RowUnconstrainedBox 一样不会对子级施加限制,一样会产生溢出警告
  • Row 的子级被包裹在 Expanded 之后,子级自身的宽度将被忽略
  • 如果所有 Row 的子级都被 Expanded 包裹,每一个 Expanded 大小都会与其 flex 因子成比例,且 Expanded 会强制子级具有与 Expanded 相同的宽度
  • FlexibleExpanded 类似,唯一的区别是 Flexible 允许其子级的宽度比它小或相等。Expanded 是强制相等

Scaffold

Scaffold 的表现

  • 屏幕强制 Scaffold 全屏,Scaffold 告诉其子级可以为任意大小,但是不能超出屏幕
  • Scaffold 的子级被 SizedBox.expand 包裹时,该子级将变得和 Scaffold 一样大

宽松约束(loose)和严格约束(Tight)

宽松约束就是设置了最大宽度,但其最小宽度为 0,高度也是

minWidth = 0.0
manWidth = size.width
minHeight = 0.0
manHeight = size.height

严格约束就是最大最小宽度是一样的,高度也是

minWidth = size.width
manWidth = size.width
minHeight = size.height
manHeight = size.height
Last Updated:
Contributors: af