Align

一个在其内部对其子组件,并可根据子组件的大小选择调整自身尺寸的组件

举个例子,想要将子组件放置外部盒子的右下角,需要给外部盒子设置比子组件原始尺寸大的紧约束,同时给外部盒子设置对齐方式为Alignment.bottomRight

Align组件的大小判断:

  1. 如果组件的尺寸有约束且widthFactorheightFactor都为null,那么Align将根据约束尽可能大
  2. 如果组件在某个方向上没有约束,且对应方向的Factor为null,那么Align在这个方向上将与子组件一样大
  3. 如果没有设置约束,但是对应的Factor有值,那么Align的宽高为子组件的宽高 * Factor值,如WidthFactor的值为2,那么Align的宽度为子组件宽度的2倍

示例

Center(
  child: Container(
    height: 120.0,
    width: 120.0,
    color: Colors.blue[50],
    child: const Align(
      alignment: Alignment.topRight,
      child: FlutterLogo(
        size: 60,
      ),
    ),
  ),
)

这个例子展示了Align组件使用Alignment.topRight,将FlutterLogo放置在父组件的右上角。

详细描述

alignment属性描述了子组件坐标系中的一个点以及Align组件所在坐标系中的另一个点。Align组件将子组件定位,让这两个点对齐,位于同一位置。

以下示例中使用的Alignment定义了两个点:

  1. FlutterLogo的坐标系中:(0.2 × FlutterLogo宽度/2 + FlutterLogo宽度/2, 0.6 × FlutterLogo高度/2 + FlutterLogo高度/2) = (36.0, 48.0)

  2. Align组件(蓝色区域)的坐标系中:(0.2 × Align宽度/2 + Align宽度/2, 0.6 × Align高度/2 + Align高度/2) = (72.0, 96.0)

Align组件会将FlutterLogo放置在这两个点重合的位置。在此示例中,FlutterLogo的左上角将位于Align组件左上角偏移(72.0, 96.0) - (36.0, 48.0) = (36.0, 48.0)的位置。

即如果设置(0, 0)则FlutterLogo的中点处于容器的中点:

  • (0,0) center
  • (-1,-1) topLeft
  • (-1,0) centerLeft
  • (-1,1) bottomLeft
  • (0,-1) topCenter
  • (0,1) bottomCenter
  • (1,-1) topRight
  • (1,0) centerRight
  • (1,1) bottomRight
Center(
  child: Container(
    height: 120.0,
    width: 120.0,
    color: Colors.blue[50],
    child: const Align(
      alignment: Alignment(0.2, 0.6),
      child: FlutterLogo(
        size: 60,
      ),
    ),
  ),
)

下面示例中使用的FractionalOffset定义了两个点:

  • (FlutterLogo宽度 * 0.2,FlutterLogo高度 * 0.6) = FlutterLogo坐标系中的 (12.0, 36.0)。
  • (Align宽度 * 0.2,Align高度 * 0.6) = Align控件(蓝色区域)坐标系中的(24.0, 72.0)。

Align控件将FlutterLogo摆放,使这两个点重合。在此示例中,FlutterLogo的左上角将被放置在Align控件左上角偏移(24.0, 72.0) - (12.0, 36.0) = (12.0, 36.0)的位置。

FractionalOffset类使用的坐标系原点在容器的左上角,与上面示例中Alignment使用的以中心为原点的坐标系不同。

Center(
  child: Container(
    height: 120.0,
    width: 120.0,
    color: Colors.blue[50],
    child: const Align(
      alignment: FractionalOffset(0.2, 0.6),
      child: FlutterLogo(
        size: 60,
      ),
    ),
  ),
)

区别

1. Alignment

坐标系:以父组件中心为原点(0, 0),x和y的范围为[-1, 1]。

示例:

  • Alignment(-1, -1) 表示左上角。
  • Alignment(1, 1) 表示右下角。
  • Alignment(0, 0) 表示中心。

特点:

  • 直观,易于理解(类似于CSS的transform-origin)。
  • 适合对称对齐(如居中、偏左/右等)。

2. FractionalOffset

坐标系:以父组件左上角为原点(0, 0),x和y的范围为[0, 1]。

示例:

  • FractionalOffset(0, 0)表示左上角。
  • FractionalOffset(1, 1)表示右下角。
  • FractionalOffset(0.5, 0.5)表示中心(等价于Alignment(0, 0))。

特点:

  • 更适合计算百分比偏移(如“距离左边 20%”)。
  • Alignment可以通过数学转换互相表示:Alignment(x, y)等价于FractionalOffset((x + 1) / 2, (y + 1) / 2)
特性AlignmentFractionalOffset
原点父组件中心(0, 0)父组件左上角(0,0)
范围[-1,-1][0,1]
直观性对称对齐更直观百分比偏移更直观
转换关系Alignment(x, y) ↔ FractionalOffset((x+1)/2, (y+1)/2)

构造函数

Align.new({
  Key? key, 
  AlignmentGeometry alignment = Alignment.center, 
  double? widthFactor, 
  double? heightFactor, 
  Widget? child
})

参数

参数名参数类型说明
alignmentAlignmentGeometry排列对齐方式
childWidget?子组件
heightFactordouble?高度系数,如果有值,则Align的高度为子组件高度 * 高度系数
widthFactordouble?宽度系数,如果有值,则Align的宽度为子组件宽度 * 宽度系数