1. Align
1.1 Align 介绍
Align 组件可以调整子组件的位置,定义如下
const Align({
Key? key,
this.alignment = Alignment.center,
this.widthFactor,
this.heightFactor,
Widget? child,
}
- alignment : 需要一个AlignmentGeometry类型的值,表示子组件在父组件中的起始位置。AlignmentGeometry 是一个抽象类,它有两个常用的子类:Alignment和 FractionalOffset,我们将在下面的示例中详细介绍。
- widthFactor和heightFactor是用于确定Align 组件本身宽高的属性;它们是两个缩放因子,会分别乘以子元素的宽、高,最终的结果就是Align 组件的宽高。如果值为null,则组件的宽高将会占用尽可能多的空间。
1.2 Align 示例
Container(
height: 120.0,
width: 120.0,
color: Colors.bule.shade50,
child: Align(
alignment: Alignment.topRight,
child: FlutterLogo(
size: 60,
),
),
)

FlutterLogo 是Flutter SDK 提供的一个组件,内容就是 Flutter 的 logo 。在上面的例子中,我们显式指定了Container的宽、高都为 120。如果我们不显式指定宽高,而通过同时指定widthFactor和heightFactor 为 2 也是可以达到同样的效果
Align(
widthFactor: 2,
heightFactor: 2,
alignment: Alignment.topRight,
child: FlutterLogo(
size: 60,
),
),
因为FlutterLogo的宽高为 60,则Align的最终宽高都为2*60=120。
1.3 Alignment
Alignment继承自AlignmentGeometry,表示矩形内的一个点,他有两个属性x、y,分别表示在水平和垂直方向的偏移,Alignment定义如下
const Alignment(this.x, this.y)
Alignment Widget会以矩形的中心点作为坐标原点,即Alignment(0.0, 0.0) 。x、y的值从-1到1分别代表矩形左边到右边的距离和顶部到底边的距离,因此2个水平(或垂直)单位则等于矩形的宽(或高),如Alignment(-1.0, -1.0) 代表矩形的左侧顶点,而Alignment(1.0, 1.0)代表右侧底部终点,而Alignment(1.0, -1.0) 则正是右侧顶点,即Alignment.topRight。为了使用方便,矩形的原点、四个顶点,以及四条边的终点在Alignment类中都已经定义为了静态常量
Alignment可以通过其坐标转换公式将其坐标转为子元素的具体偏移坐标:
(Alignment.x*childWidth/2+childWidth/2, Alignment.y*childHeight/2+childHeight/2)
其中childWidth为子元素的宽度,childHeight为子元素高度。
现在我们再看看上面的示例,我们将Alignment(1.0, -1.0)带入上面公式,可得FlutterLogo的实际偏移坐标正是(60,0)
下面再看一个例子:
Align(
widthFactor: 2,
heightFactor: 2,
alignment: Alignment(2,0.0),
child: FlutterLogo(
size: 60,
),
)
我们可以先想象一下运行效果:将Alignment(2,0.0)带入上述坐标转换公式,可以得到FlutterLogo的实际偏移坐标为(90,30)

1.4 FractionalOffset
FractionalOffset 继承自 Alignment,它和 Alignment唯一的区别就是坐标原点不同!FractionalOffset 的坐标原点为矩形的左侧顶点,这和布局系统的一致,所以理解起来会比较容易。FractionalOffset的坐标转换公式为:
实际偏移 = (FractionalOffse.x * childWidth, FractionalOffse.y * childHeight)
示例:
Container(
height: 120.0,
width: 120.0,
color: Colors.blue[50],
child: Align(
alignment: FractionalOffset(0.2, 0.6),
child: FlutterLogo(
size: 60,
),
),
)

我们将FractionalOffset(0.2, 0.6)带入坐标转换公式得FlutterLogo实际偏移为(12,36),和实际运行效果吻合。
2. Center
Center组件继承自Align,只是将alignment设置为Alignment.center
const Center({ Key? key, double? widthFactor, double? heightFactor, Widget? child })
: super(key: key, widthFactor: widthFactor, heightFactor: heightFactor, child: child);
示例
class CenterDemo extends StatelessWidget {
const CenterDemo({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Center(
widthFactor: 2,
heightFactor: 2,
child: Container(
color: Colors.red,
width: 60,
height: 60,
),
);
}
}
参考:https://book.flutterchina.club/chapter4/alignment.html#_4-7-1-align