咱们讲过经过Stack
和Positioned
,咱们能够指定一个或多个子元素相对于父元素各个边的准确偏移,而且能够重叠。但假如咱们只想简略的调整一个子元素在父元素中的方位的话,运用Align
组件会更简略一些。
Align
Align
组件能够调整子组件的方位,界说如下:
Align({
Key key,
this.alignment = Alignment.center,
this.widthFactor,
this.heightFactor,
Widget child,
})
- alignment : 需求一个AlignmentGeometry类型的值,表明子组件在父组件中的起始方位。AlignmentGeometry 是一个抽象类,它有两个常用的子类:Alignment和 FractionalOffset,咱们将在下面的示例中具体介绍。
- widthFactor和heightFactor是用于确认Align 组件本身宽高的属性;它们是两个缩放因子,会别离乘以子元素的宽、高,终究的结果便是Align 组件的宽高。假如值为null,则组件的宽高将会占用尽可能多的空间。
咱们先来看一个简略的比如:
Container(
height: 120.0,
width: 120.0,
color: Colors.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
。
另外,咱们经过Alignment.topRight
将FlutterLogo
定位在Container
的右上角。那Alignment.topRight
是什么呢?经过源码咱们能够看到其界说如下:
//右上角
static const Alignment topRight = Alignment(1.0, -1.0);
能够看到它仅仅Alignment
的一个实例,下面咱们介绍一下Alignment
。
Alignment
Alignment
承继自AlignmentGeometry
,表明矩形内的一个点,他有两个属性x
、y
,别离表明在水平缓笔直方向的偏移,Alignment
界说如下:
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)。下面再看一个比如:
Container(
color: Colors.blue.shade100,
child: const Align(
widthFactor: 2,
heightFactor: 2,
alignment: Alignment(2.0,0),
child: FlutterLogo(size: 60,),
),)
咱们能够先想象一下运转作用:将Alignment(2,0.0)
带入上述坐标转化公式,能够得到FlutterLogo
的实践偏移坐标为(90,30)。
FractionalOffset
FractionalOffset
承继自 Alignment
,它和 Alignment
唯一的差异便是坐标原点不同!FractionalOffset
的坐标原点为矩形的左侧极点,这和布局体系的一致,所以了解起来会比较简单。FractionalOffset
的坐标转化公式为:
实践偏移 = (FractionalOffse.x * childWidth, FractionalOffse.y * childHeight)
比如:
Container(
height: 120,
width: 120,
color: Colors.blue[100],
child: const Align(alignment: FractionalOffset(0.2,0.9),
child: FlutterLogo(size: 60,),
),
)
实践运转作用如图
咱们将FractionalOffset(0.2, 0.9)
带入坐标转化公式得FlutterLogo
实践偏移为(12,54),和实践运转作用符合。
Align和Stack对比
能够看到,Align和Stack/Positioned都能够用于指定子元素相对于父元素的偏移,但它们仍是有两个主要差异:
- 定位参考体系不同;Stack/Positioned定位的的参考系能够是父容器矩形的四个极点;而Align则需求先经过alignment 参数来确认坐标原点,不同的alignment会对应不同原点,终究的偏移是需求经过alignment的转化公式来计算出。
- Stack能够有多个子元素,而且子元素能够堆叠,而Align只能有一个子元素,不存在堆叠。
Center组件
Center为居中定位元素组件。经过查找SDK源码,咱们看到Center
组件界说如下:
class Center extends Align {
const Center({ Key? key, double widthFactor, double heightFactor, Widget? child })
: super(key: key, widthFactor: widthFactor, heightFactor: heightFactor, child: child);
}
能够看到Center承继自Align,它比Align只少了一个alignment 参数;由于Align的结构函数中alignment 值为Alignment.center,所以,咱们能够认为Center组件其实是对齐方法确认(Alignment.center)了的Align。
上面咱们讲过当widthFactor或heightFactor为null时组件的宽高将会占用尽可能多的空间,这一点需求特别注意,咱们经过一个示例说明:
...//省略无关代码
DecoratedBox(
decoration: BoxDecoration(color: Colors.red),
child: Center(
child: Text("xxx"),
),
),
DecoratedBox(
decoration: BoxDecoration(color: Colors.red),
child: Center(
widthFactor: 1,
heightFactor: 1,
child: Text("xxx"),
),
)
运转作用:
总结
Align
组件及两种偏移类Alignment
和FractionalOffset
,需求了解这两种偏移类的差异及各自的坐标转化公式。另外,在此主张读者在需求制定一些准确的偏移时应优先运用FractionalOffset
,由于它的坐标原点和布局体系相同,能更简单算出实践偏移。
还有,熟悉Web开发的同学可能会发现Align组件的特性和Web开发中相对定位(position: relative)十分像,是的!在大多数时候,咱们能够直接运用Align组件来完成Web中相对定位的作用。
完好demo源码:flutter_demo: flutter组件测试学习demo
本文正在参与「金石计划 . 瓜分6万现金大奖」