Flutter入门-修饰类容器-Padding、Align以及Center

75 阅读3分钟

Padding

通过Padding,可以有效地在子级的四周创建空的区域,内边距的空白区域,也是widget的一部分。

Padding的布局分为两种情况:

  • 当child为空的时候,会创建一个宽为left+right,高为top+bottom的区域;
  • 当child不为空的时候,Padding会将布局的约束传递给child,根据设置的padding属性,缩小child的布局尺寸。然后Padding将自己调整到child设置了padding属性的尺寸,在child周围创建空白区域
void performLayout() {
    final BoxConstraints constraints = this.constraints;
    _resolve();
    assert(_resolvedPadding != null);
    if (child == null) {
      size = constraints.constrain(Size(
        _resolvedPadding!.left + _resolvedPadding!.right,
        _resolvedPadding!.top + _resolvedPadding!.bottom,
      ));
      return;
    }
    final BoxConstraints innerConstraints = constraints.deflate(_resolvedPadding!);
    child!.layout(innerConstraints, parentUsesSize: true);
    final BoxParentData childParentData = child!.parentData! as BoxParentData;
    childParentData.offset = Offset(_resolvedPadding!.left, _resolvedPadding!.top);
    size = constraints.constrain(Size(
      _resolvedPadding!.left + child!.size.width + _resolvedPadding!.right,
      _resolvedPadding!.top + child!.size.height + _resolvedPadding!.bottom,
    ));
  }

使用 Padding

const Card( 
    child: Padding( 
        padding: EdgeInsets.all(20.0), 
        child: Text('IAM17'), ), )

使用 Padding Widget 还是很简单的。这一个例子代表所有了。建议仔细阅读 Padding 的源码,对于理解 RenderShiftedBox 非常适合。

最后再说一下padding 属性的常用写法。

代码效果
EdgeInsets.all(20.0)四个方向都为 20
EdgeInsets.zero四个方向都为 0
EdgeInsets.fromLTRB(10, 20,30, 40)左10,上20,右30,下40
EdgeInsets.only(top:20)上20,也可以单独指定右下左。
EdgeInsets.symmetric(horizontal: 20)左右各20,也可以指定上下各 20.

设计缘由

为什么要使用一个Padding Widget组件,而不是一个 Container 容器用一个Container.padding 属性?

实际上两者的本质没有任何区别,如果你用了Container.padding 参数,那么 Container 实际上也是会帮你创建一个简单的 Padding Widget。Padding本身是非常简单的,基本上需要间距的地方,它都能够使用;如果在单一的内间距场景,使用Padding比Container的成本要小一些,因为Container里面除了Padding,它还包含了很多个widget。Padding能够实现的,Container都能够实现,只不过,Container提供的东西更多。Container 将许多更简单的小部件组合到一个 package 去进去了。

实际上,Flutter中的大多数Widgets都只是其他更简单的Widgets的组合。组合而不是继承,这是是构建Widgets的主要机制

Align

Align组件可以调整子组件的位置,并且可以根据子组件的宽高来确定自身的宽高

构造函数如下:

Align({
  Key key,
  this.alignment = Alignment.center,
  this.widthFactor,
  this.heightFactor,
  Widget child,
})

布局表现

Align的布局行为分为两种情况:

  • 当widthFactor和heightFactor为null的时候,当其有限制条件的时候,Align会根据限制条件尽量的扩展自己的尺寸,当没有限制条件的时候,会调整到child的尺寸;
  • 当widthFactor或者heightFactor不为null的时候,Aligin会根据factor属性,扩展自己的尺寸,例如设置widthFactor为2.0的时候,那么,Align的宽度将会是child的两倍

Align 的属性

属性类型作用
keyKey?组件的标示
alignmentAlignmentGeometry子节点的对齐方法,一般设置为 Alignment
widthFactordouble?宽度因子,Align 的宽度 = 子节点的宽度 * 宽度因子
heightFactordouble?高度因子,Align 的高度 = 子节点的高度 * 高度因子
childWidget?待对齐的子节点

Alignment

在上面的例子中,我们指定了图片的位置alignment: Alignment.topRight, 意思就是显示在右上角,当然还有其他的值,例如:

  • topLeft 左上角
  • topRight 右上角
  • topCenter 上中
  • center 中心
  • centerLeft 左中
  • centerRight 右中
  • bottomLeft 左下角
  • bottomCenter 下中
  • bottomRight 右下角

image.png

Center

Center继承自Align,只不过是将alignment设置为Alignment.center,其他属性例如widthFactor、heightFactor,布局行为,都与Align完全一样