【布局 widget】 Flutter FractionallySizedBox

大家好,我是 17。

FractionallySizedBox 是布局 widget,可以给 child tight 约束,多用于按比例填充空白。

 BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
    
    
    double minWidth = constraints.minWidth;
    double maxWidth = constraints.maxWidth;
    if (_widthFactor != null) {
    
    
      final double width = maxWidth * _widthFactor!;
      minWidth = width;
      maxWidth = width;
    }
    double minHeight = constraints.minHeight;
    double maxHeight = constraints.maxHeight;
    if (_heightFactor != null) {
    
    
      final double height = maxHeight * _heightFactor!;
      minHeight = height;
      maxHeight = height;
    }
    return BoxConstraints(
      minWidth: minWidth,
      maxWidth: maxWidth,
      minHeight: minHeight,
      maxHeight: maxHeight,
    );
  }
 void performLayout() {
    
    
    if (child != null) {
    
    
      child!.layout(_getInnerConstraints(constraints), parentUsesSize: true);
      size = constraints.constrain(child!.size);
      alignChild();
    } else {
    
    
      size = constraints.constrain(_getInnerConstraints(constraints).constrain(Size.zero));
    }
  }

上面两段代码就是 FractionallySizedBox 的布局逻辑。我们从三个方面来描述一下。

  1. 确定 child 的 constrains
  2. 确定 自己的大小
  3. 摆放 child。

确定 child constrains

constrains 是 tight ,FractionallySizedBox 透传 constrains 给 child。

constrains 是 loose,widthFactor 为空,FractionallySizedBox 透传 minWidth,maxWith 给 child;heightFactor 为空,FractionallySizedBox 透传 minHeight,maxHeight 给 child。

constrains 是 loose,widthFactor 不为空, 在 constrains 范围内 给 child 的 width tight 约束;heightFactor 不为空 在 constrains 范围内 给 child 的 height tight 约束。

举个例子:

ConstrainedBox(
    constraints: const BoxConstraints(
        minWidth: 0,
        maxWidth: 100,
        minHeight: 0,
        maxHeight: 100),
    child: FractionallySizedBox(
      widthFactor: 0.5,
      child: Container(
        color: Colors.green[400],
      ),
));

widthFactor 不为空,child 的宽受到 tight 约束,值为 100 * 0.5 等于 50。

heightFactor 为空,FractionallySizedBox 将 约束透传给 child。Container 在没有 child 的情况下会尽量大,所以高度为 100。

widthFactor 和 heightFactor 必须大于 0,可以大于 1 ,所以 child 的大小可以超出 parent

确定自己的大小

简单来说,FractionallySizedBox 的大小不会超过 constrains 的范围。在这个前提下,FractionallySizedBox 尽量和 child 一样大。如果没有 child 尽量取 widthFactor,heightFactor 设定的值。

摆放 child

通过 alignment 参数摆放 child。只有 FractionallySizedBox 与 child 不一样大的时候才会有效果。

应用场景

按比例填充空白

Container(
  width: 100,
  height: 100,
  child: FractionallySizedBox(
    widthFactor: 0.8,
    heightFactor: 0.8,
    decoration: BoxDecoration(border: Border.all(color: Colors.blue,width: 2)),
    child: Container(
      color: Colors.green[400],
    ),
  ))

虽然用 container 的 padding 也能做到空白,但不能弹性变化。

FractionallySizedBox 能用在 Row ,Column 中,但需要用 Flexible 包起来。

FractionallySizedBox 可以允许 child 超出父容器,做溢出效果,但是如果溢出,用 OverflowBox 可读性会更好些。

与 SizedBox 比较

SizedBox 和 FractionallySizedBox 都可以给 child tight 约束。

虽然都可以填充空白,但是场景不同。SizedBox 是在同级的兄弟之间填充空白,FractionallySizedBox 是在父子之间填充空白。

SizedBox 的 child 必须在 constrains 范围之内,FractionallySizedBox 的 child 可以超出 constrains 范围。

猜你喜欢

转载自blog.csdn.net/m0_55635384/article/details/128873365