前端开发进阶篇——Flutter布局
1. 线性布局(Row和Column)
线性布局,即指沿水平或垂直方向排布子组件。Flutter中通过Row和Column来实现线性布局,Row和Column都继承自Flex。Row控件可以分为灵活排列和非灵活排列两种。
Row(Column)可以在水平方向排列其子widget,其定义为:
Row({ ... TextDirection textDirection, MainAxisSize mainAxisSize = MainAxisSize.max, MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, VerticalDirection verticalDirection = VerticalDirection.down, CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, List<Widget> children = const <Widget>[],})
textDirection:表示水平方向子组件的布局顺序(是从左往右还是从右往左)。
mainAxisSize:表示Row在主轴(水平)方向占用的空间,默认是MainAxisSize.max,表示尽可能多的占用水平方向的空间,此时无论子widgets实际占用多少水平空间,Row的宽度始终等于水平方向的最大宽度;而MainAxisSize.min表示尽可能少的占用水平空间,当子组件没有占满水平剩余空间,则Row的实际宽度等于所有子组件占用的的水平空间;
mainAxisAlignment:表示子组件在Row所占用的水平空间内对齐方式。
1)MainAxisAlignment.start表示沿textDirection的初始方向对齐。
2)textDirection取值为TextDirection.ltr时,则MainAxisAlignment.start表示左对齐,
3)textDirection取值为TextDirection.rtl时表示从右对齐。
4)而MainAxisAlignment.end和MainAxisAlignment.start正好相反;
5)MainAxisAlignment.center表示居中对齐。
verticalDirection:表示Row纵轴(垂直)的对齐方向,默认是VerticalDirection.down,表示从上到下。
crossAxisAlignment:表示子组件在纵轴方向的对齐方式,Row的高度等于子组件中最高的子元素高度。它的取值和MainAxisAlignment:start、end、 center。不同的是crossAxisAlignment的参考系是verticalDirection,即verticalDirection值为VerticalDirection.down时,crossAxisAlignment.start指顶部对齐,verticalDirection值为VerticalDirection.up时,crossAxisAlignment.start指底部对齐;而crossAxisAlignment.end和crossAxisAlignment.start正好相反;
children :子组件数组。
2. 弹性布局(Flex)
弹性布局允许子组件按照一定比例来分配父容器空间。Flutter中的弹性布局主要通过Flex和Expanded来配合实现。Flex组件可以沿着水平或垂直方向排列子组件,使用Row或Column会方便一些,因为Row和Column都继承自Flex,参数基本相同。
例子如下:
body:Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Center(child:Text('I am xiaotuanzi')), Expanded(child:Center(child:Text('I am a student'))), Center(child:Text('I love coding')) ], )
3. 流式布局
如果子widget超出屏幕范围,则会报溢出错误。我们把超出屏幕显示范围会自动折行的布局称为流式布局。Flutter中通过Wrap
和Flow
来支持流式布局。
Wrap定义如下:
Wrap({ ... this.direction = Axis.horizontal, this.alignment = WrapAlignment.start, this.spacing = 0.0, this.runAlignment = WrapAlignment.start, this.runSpacing = 0.0, this.crossAxisAlignment = WrapCrossAlignment.start, this.textDirection, this.verticalDirection = VerticalDirection.down, List<Widget> children = const <Widget>[],})
spacing:主轴方向子widget的间距
runSpacing:纵轴方向的间距
runAlignment:纵轴方向的对齐方式
4. 层叠布局 Stack、Positioned
水平布局和垂直布局确实很好用,但是有一种情况是无法完成的,比如放入一个图片,图片上再写一些字或者放入容器。子组件可以根据距父容器四个角的位置来确定自身的位置。Flutter中使用Stack和Positioned这两个组件来配合实现绝对定位。Stack允许子组件堆叠,而Positioned用于根据Stack的四个角来确定子组件的位置。
1)Stcak定义如下:
Stack({ this.alignment = AlignmentDirectional.topStart, this.textDirection, this.fit = StackFit.loose, this.overflow = Overflow.clip, List<Widget> children = const <Widget>[],})
alignment:alignment属性是控制层叠的位置的。
textDirection:和Row、Wrap的textDirection功能一样,都用于确定alignment对齐的参考系,即:textDirection的值为TextDirection.ltr,则alignment的start代表左,end代表右,即从左往右的顺序;textDirection的值为TextDirection.rtl,则alignment的start代表右,end代表左,即从右往左的顺序。
fit:此参数用于确定没有定位的子组件如何去适应Stack的大小。StackFit.loose表示使用子组件的大小,StackFit.expand表示扩伸到Stack的大小。
overflow:此属性决定如何显示超出Stack显示空间的子组件;值为Overflow.clip时,超出部分会被剪裁(隐藏),值为Overflow.visible 时则不会。
2)Positioned定义如下:
const Positioned({ Key key, this.left, this.top, this.right, this.bottom, this.width, this.height, @required Widget child,})
left、top 、right、 bottom分别代表离Stack左、上、右、底四边的距离。
width和height用于指定需要定位元素的宽度和高度。
5. 对齐与相对定位(Align)
通过Stack和Positioned,我们可以指定一个或多个子元素相对于父元素各个边的精确偏移,并且可以重叠。但如果我们只想简单的调整一个子元素在父元素中的位置的话,使用Align组件会更简单一些。
Align 组件可以调整子组件的位置,并且可以根据子组件的宽高来确定自身的的宽高,定义如下:
Align({ Key key, this.alignment = Alignment.center, this.widthFactor, this.heightFactor, Widget child,})
alignment : 需要一个AlignmentGeometry类型的值,表示子组件在父组件中的起始位置。AlignmentGeometry 是一个抽象类,它有两个常用的子类:Alignment和 FractionalOffset。表示矩形内的一个点,他有两个属性
x
、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.x*childWidth/2+childWidth/2, Alignment.y*childHeight/2+childHeight/2),其中childWidth为子元素的宽度,childHeight为子元素高度。
widthFactor和heightFactor:是用于确定Align 组件本身宽高的属性;它们是两个缩放因子,会分别乘以子元素的宽、高,最终的结果就是Align 组件的宽高。如果值为null,则组件的宽高将会占用尽可能多的空间。
FractionalOffset继承自 Alignment,它和 Alignment唯一的区别就是坐标原点不同!FractionalOffset 的坐标原点为矩形的左侧顶点。FractionalOffset的坐标转换公式为:实际偏移 = (FractionalOffse.x * childWidth, FractionalOffse.y * childHeight)。
- 点赞
- 收藏
- 关注作者
评论(0)