Flutter布局
Flutter 中拥有需要将近30种内置的 布局Widget,其中常用有 Container、Padding、Center、Flex、Stack、Row、Column、ListView 等,下面简单讲解它们的特性和使用。
| 布局 | 类型 | 作用特点 |
|---|---|---|
| 容器 | Container | 只有一个子 Widget。默认充满,包含了padding、margin、color、宽高、decoration 等配置。 |
| 可滚动 | GridView | 使用GridView将widget放置为二维列表。 GridView提供了两个预制list,或者您可以构建自定义网格。当GridView检测到其内容太长而不适合渲染框时,它会自动滚动 |
| 居中 | Center | 只有一个子 Widget。只用于居中显示,常用于嵌套child,给child设置居中。 |
| 层叠 | Stack | 可以有多个子 Widget。 子Widget堆叠在一起。 |
| 线性 | Column | 可以有多个子 Widget。垂直布局。如果子widget超出屏幕范围,则会报溢出错误 |
| 线性 | Row | 可以有多个子 Widget。水平布局。如果子widget超出屏幕范围,则会报溢出错误 |
| 填充 | Expanded | 只有一个子 Widget。在 Column 和 Row 中充满。 |
| 可滚动 | ListView | 是一个类似列的widget,它的内容对于其渲染框太长时会自动提供滚动。 |
| 卡片 | Card | 接受单个子项,但该子项可以是Row,Column或其他包含子级列表的widget,显示圆角和阴影,Card内容不能滚动 |
| 弹性 | Flex | 如H5中的弹性盒子布局,主要通过Flex和Expanded来配合实现 |
Container介绍
- Container:最常用的默认控件,但是实际上它是由多个内置控件组成的模版,只能包含一个child,支持 padding,margin,color,宽高,decoration(一般配置边框和阴影)等配置,在 Flutter 中,不是所有的控件都有 宽高、padding、margin、color 等属性,所以才会有 Padding、Center 等 Widget 的存在。bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14new Container(
margin: EdgeInsets.all(20.0),
height: 120.0,
width: 500.0,
///透明黑色遮罩
decoration: new BoxDecoration(
//弧度为10.0
borderRadius: BorderRadius.all(Radius.circular(10.0)),
//设置了decoration的color,就不能设置Container的color。
color: Colors.black,
//边框
border: new Border.all(color: Colors.blue, width: 0.3)),
child:new Text("xixi")
);
线性布局(Column、Row)介绍
- Column、Row 所谓线性布局,即指沿水平或垂直方向排布子组件。它们常用的有这些属性配置:主轴方向是 start 或 center 等;副轴方向方向是 start 或 center 等;mainAxisSize 是充满最大尺寸,或者只根据子 Widget 显示最小尺寸。
主轴和纵轴对于线性布局,有主轴和纵轴之分,如果布局是沿水平方向,那么主轴就是指水平方向,而纵轴即垂直方向;如果布局沿垂直方向,那么主轴就是指垂直方向,而纵轴就是水平方向。在线性布局中,有两个定义对齐方式的枚举类MainAxisAlignment和CrossAxisAlignment,分别代表主轴对齐和纵轴对齐。
bash1
2
3
4
5
6//主轴方向,Column的竖向、Row的横向
mainAxisAlignment: MainAxisAlignment.start,
//默认是最大充满、还是根据child显示最小大小
mainAxisSize: MainAxisSize.max,
//副轴方向,Column的横向、Row的竖向
crossAxisAlignment :CrossAxisAlignment.center,
Row 布局
dart
1 | new Column( |
解释:
- 第一个Row很简单,默认为居中对齐;第二个Row,由于mainAxisSize值为MainAxisSize.min,Row的宽度等于两个Text的宽度和,所以对齐是无意义的,所以会从左往右显示;第三个Row设置textDirection值为TextDirection.rtl,所以子组件会从右向左的顺序排列,而此时MainAxisAlignment.end表示左对齐,所以最终显示结果就是图中第三行的样子;第四个Row测试的是纵轴的对齐方式,由于两个子Text字体不一样,所以其高度也不同,我们指定了verticalDirection值为VerticalDirection.up,即从低向顶排列,而此时crossAxisAlignment值为CrossAxisAlignment.start表示底对齐。
Column 布局
Column可以在垂直方向排列其子组件。参数和Row一样,不同的是布局方向为垂直,主轴纵轴正好相反,读者可类比Row来理解,下面看一个例子:dart
1 | import 'package:flutter/material.dart'; |
解释
- 由于我们没有指定Column的mainAxisSize,所以使用默认值MainAxisSize.max,则Column会在垂直方向占用尽可能多的空间,此例中为屏幕高度。
- 由于我们指定了 crossAxisAlignment 属性为CrossAxisAlignment.center,那么子项在Column纵轴方向(此时为水平方向)会居中对齐。注意,在水平方向对齐是有边界的,总宽度为Column占用空间的实际宽度,而实际的宽度取决于子项中宽度最大的Widget。在本例中,Column有两个子Widget,而显示“world”的Text宽度最大,所以Column的实际宽度则为Text(“world”) 的宽度,所以居中对齐后Text(“hi”)会显示在Text(“world”)的中间部分。
实际上,Row和Column都只会在主轴方向占用尽可能大的空间,而纵轴的长度则取决于他们最大子元素的长度。
特殊情况
如果Row里面嵌套Row,或者Column里面再嵌套Column,那么只有对最外面的Row或Column会占用尽可能大的空间,里面Row或Column所占用的空间为实际大小,下面以Column为例说明:
dart
1 | Container( |
如果要让里面的Column占满外部Column,可以使用Expanded 组件
dart
1 | Expanded( |
弹性布局(Flex)
Expanded 介绍
- Expanded 在 Column 和 Row 中代表着平均充满的作用,当有两个存在的时候默认均分充满。同时页可以设置 flex 属性决定比例。bash
1
2
3
4
5
6
7
8
9
10
11
12
13new Column(
///主轴居中,即是竖直向居中
mainAxisAlignment: MainAxisAlignment.center,
///大小按照最小显示
mainAxisSize : MainAxisSize.min,
///横向也居中
crossAxisAlignment : CrossAxisAlignment.center,
children: <Widget>[
///flex默认为1
new Expanded(child: new Text("1111"), flex: 2,),
new Expanded(child: new Text("2222")),
],
);

