弹性布局允许子组件按照一定比例来分配父容器空间
为凤阳等地区用户提供了全套网页设计制作服务,及凤阳网站建设行业解决方案。主营业务为成都做网站、网站制作、凤阳网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
Flex组件和Row、Column属性主要的区别就是多一个direction。
当direction的值为Axis.horizontal的时候,则是Row。
当direction的值为Axis.vertical的时候,则是Column。
它们之中都有主轴(MainAxis)和交叉轴(CrossAxis)的概念:
Row可以沿水平方向排列其子widget。定义如下:
示例1 - 基本使用
示例2 - 基线对齐
基线是英文字母X的下端两点连成的一条线
示例3 - 水平方向包裹
Column可以沿垂直方向排列其子widget。定义如下:
Column 基本使用 示例
再看一个示例
运行效果如下:
我们发现文本并没有居中?
解释:
实际上,Row和Column都只会在主轴方向占用尽可能大的空间,而交叉轴的长度则取决于他们最大子元素的长度。如果我们想让本例中的两个文本控件在整个手机屏幕中间对齐,我们有两种方法:
运行效果如下:
如果Row里面嵌套Row,或者Column里面再嵌套Column,那么只有最外面的Row或Column会占用尽可能大的空间,里面Row或Column所占用的空间为实际大小,下面以Column为例说明
如果要让里面的Column占满外部Column,可以使用Expanded 组件:
Row:在水平方向上排列子widget的列表。
Column:在垂直方向上排列子widget的列表。
注意:这两个属于多子节点空间,可以将children排列成一行/一列,但是自身不带滚动属性,如果超出了一行,在debug下面则会显示溢出的提示。
MainAxisAlignment:主轴方向上的对齐方式,会对child的位置起作用,默认是start。
其中MainAxisAlignment枚举值:
center:将children放置在主轴的中心;
end:将children放置在主轴的末尾;
spaceAround:将主轴方向上的空白区域均分,使得children之间的空白区域相等,但是首尾child的空白区域为1/2;
spaceBetween:将主轴方向上的空白区域均分,使得children之间的空白区域相等,首尾child都靠近首尾,没有间隙;
spaceEvenly:将主轴方向上的空白区域均分,使得children之间的空白区域相等,包括首尾child;
start:将children放置在主轴的起点;
其中spaceAround、spaceBetween以及spaceEvenly的区别,就是对待首尾child的方式。其距离首尾的距离分别是空白区域的1/2、0、1。
MainAxisSize:在主轴方向占有空间的值,默认是max。
MainAxisSize的取值有两种:
max:根据传入的布局约束条件,最大化主轴方向的可用空间;
min:与max相反,是最小化主轴方向的可用空间;
CrossAxisAlignment:children在交叉轴方向的对齐方式,与MainAxisAlignment略有不同。
CrossAxisAlignment枚举值有如下几种:
baseline:在交叉轴方向,使得children的baseline对齐;
center:children在交叉轴上居中展示;
end:children在交叉轴上末尾展示;
start:children在交叉轴上起点处展示;
stretch:让children填满交叉轴方向;
TextDirection:阿拉伯语系的兼容设置,一般无需处理。
VerticalDirection:定义了children摆放顺序,默认是down。
VerticalDirection枚举值有两种:
down:从top到bottom进行布局;
up:从bottom到top进行布局。
top对应Row以及Column的话,就是左边和顶部,bottom的话,则是右边和底部。
TextBaseline:使用的TextBaseline的方式,有两种,前面已经介绍过。
这个是Row/Column的内的小控件,可以用来实现权重的布局
这边使用一个Container,里面是Row,使用Expanded对子节点进行权重处理,如果不使用Expanded,直接放入其他控件也是可以的,只是无法设置权重
对于内容过长的时候,会有溢出提示:
MainAxisAlignment.center:将children放置在主轴的中心;
MainAxisAlignment.start:将children放置在主轴的起点;
MainAxisAlignment.end:将children放置在主轴的末尾;
MainAxisAlignment.spaceAround:将主轴方向上的空白区域均分,使得children之间的空白区域相等,但是首尾child的空白区域为1/2;
MainAxisAlignment.spaceBetween:将主轴方向上的空白区域均分,使得children之间的空白区域相等,首尾child都靠近首尾,没有间隙;
MainAxisAlignment.spaceEvenly:将主轴方向上的空白区域均分,使得children之间的空白区域相等,包括首尾child;
下一章我们学习基础组件之Image
相对于iOS开发,Flutter的布局更具有灵活性,每个页面设计都不一样,相同页面可选择的布局方式也不一样,如果单纯的说应该如何去布局,我觉得不现实,大家可以参考下 Flutter官方的布局教程 。接下来,笔者,通过项目中的一个页面,来一步一步的拆解布局的流程。整个过程,基本上按照拆解、组件封装、具体布局这三步来的。
根据设计图,可以看出整体可以分成两部分,上面一部分是系统介绍模块,下面一部分是真正的登录内容,因为涉及到叠加,因此考虑用Stack;
系统介绍模块部分:整体也是涉及到叠加,考虑用Stack,分为四部分。最底部渐变色背景用一个contanier,无须指定位置,全视图扩展;载放logo图标在上一层,用Image。最后两个Text同级放在最上层。Image,Text各用Positioned包裹去指定位置。
登录内容模块是最外层是一个Contanier容器,去控制背景色和圆角。然后是一个Column元素,逐行排列。
第一行为Image,
第二行为Text,
第三行可以看成一个小Column,分两块进行布局
第四行可以看成一个小Column,分两块进行布局
第五行可以看作一个TextButton,
第六行可以看作一个Row,分三块进行布局
通过上面这样一步一步的分析后,基本上对大致的布局有了一个了解,最外层的控件大致选对(只要能实现的话,就是复杂度以及效率的问题),然后一步一步的拆解每一行的元素,如果有重复的或者觉得可以封装出来的部分,则进行下一步。
每一行的拆解,大致也是按照这个思路来进行,因此笔者在这里就不做讲解了。
在做到第三第四行的时候,发现这两个很相似,而且设计到一些交互逻辑,笔者就想对第三第四行的这种展示进行封装,觉得今后的布局可能会用到,因此在这一步,可以先把这一块儿抽离出一个控件。利用TextField来实现这种输入操作,具体的实现笔者不再详细的描述了。
经过这一步,整体的规划设计图已经有了,各个组件也都有了,接下来的工作就是组装了。
具体布局设计到一些细节的地方,例如整体Column的居中对齐(crossAxisAlignment)、间隔(Padding或Container包裹,笔者更喜欢用SizedBox占位)、居左居右居中(Align)、点击事件(GestureDetector)以及圆角(BorderRadius)等一些特殊情况。
像第六行row是放在底部的,就可以在第六行前面增加一个Spacer()去填充空白区域。
对文字颜色大小等,可以用TextStyle直接设置。
对于输入框的删除按钮,可以用Offstage这种Flutter特有的控制显示隐藏的控件。