本文是总结 Flutter 的的布局方式。
简单的布局控件
Align
Container(
child: Align(
alignment: Alignment.center,// 对齐方式
widthFactor: 2.0,// 宽度因子,如果设置了宽度因子,则宽度会按照子节点的宽度*宽度因子数
heightFactor: 4.0,// 高度因子,同上
child: Text("test"),// 子控件
),
color: Colors.blue,
)
Center
继承于 Align,alignment: Alignment.center。
Container(
child: Center(
widthFactor: 2.0,// 宽度因子,如果设置了宽度因子,则宽度会按照子节点的宽度*宽度因子数
heightFactor: 4.0,// 高度因子,同上
child: Text("test"),// 子控件
),
color: Colors.blue,
)
Padding
用于设置内边距
Container(
child: Padding(
padding: EdgeInsets.fromLTRB(10, 10, 10, 10),// 设置内边距
child: Text("test"),// 子控件
),
color: Colors.blue,
)
Flex 流式布局
Row 和 Column:横向流式布局、纵向流式布局
Row({
Key key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
MainAxisSize mainAxisSize = MainAxisSize.max,
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
TextDirection textDirection,
VerticalDirection verticalDirection = VerticalDirection.down,
TextBaseline textBaseline,
List children = const [],
})
mainAxisAlignment:子控件的对齐方式,默认start
- start:将children放置在主轴的起点;
- center:将children放置在主轴的中心;
- end:将children放置在主轴的末尾;
- spaceAround:将主轴方向上的空白区域均分,使得children之间的空白区域相等,但是首尾child的空白区域为1/2;
- spaceBetween:将主轴方向上的空白区域均分,使得children之间的空白区域相等,首尾child都靠近首尾,没有间隙;
- spaceEvenly:将主轴方向上的空白区域均分,使得children之间的空白区域相等,包括首尾child;
mainAxisSize:控件占有空间
- MainAxisSize.max:占满父控件
- MainAxisSize.min:子控件大小
crossAxisAlignment:子控件的对齐方式,默认center
- CrossAxisAlignment.center:居中对齐
- CrossAxisAlignment.start:顶部对齐(Row)、左边对齐(Column)
- CrossAxisAlignment.end:底部对齐(Row)、右边对齐(Column)
- CrossAxisAlignment.baseline:根据baseline对齐(只对Row生效)
- CrossAxisAlignment.stretch:撑满高度(Row)、撑满宽度(Column)
textDirection:兼容阿拉伯语的从右往左
- TextDirection.ltr:默认,从左往右
- TextDirection.rtl:从右往左
verticalDirection:children摆放顺序,默认是down
- VerticalDirection.down:从上往下
- VerticalDirection.up:从下往上
textBaseline:文字对齐方式
- TextBaseline.ideographic:用于对齐字母字符的字形底部的水平线。
- TextBaseline.alphabetic:用于对齐表意字符的水平线。
Expanded:用于约束流式布局的大小
Row(
children: [
Expanded(flex: 2, child: Text("test1")),
Expanded(flex: 1, child: Text("text2")),
],
);
flex:设置占据的比例
Standard widgets
Container
向 widget 增加 padding、margins、borders、background color 或者其他的装饰。
Container({
Key key,
this.alignment, // 对齐方式
this.padding,
Color color, // 背景色
Decoration decoration,
this.foregroundDecoration,
double width,
double height,
BoxConstraints constraints, // 可以设置边框
this.margin,
this.transform,
this.child,
})
Stack
将 widget 覆盖在另一个的上面。
Stack({
Key key,
this.alignment = AlignmentDirectional.topStart,
this.textDirection,
this.fit = StackFit.loose,
this.overflow = Overflow.clip,
List children = const [],
})
GridView
将 widget 展示为一个可滚动的网格。
GridView({
Key key,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller,
bool primary,
ScrollPhysics physics,
bool shrinkWrap = false,
EdgeInsetsGeometry padding,
@required this.gridDelegate,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
double cacheExtent,
List children = const [],
int semanticChildCount,
})
示例
GridView.count(
crossAxisCount: 2, // 横向数量
padding: EdgeInsets.all(8),
mainAxisSpacing: 8, // 子控件纵向间隔
crossAxisSpacing: 8, // 子控件横向间隔
children: [
Container(height: 100,color: Colors.grey,),
Container(height: 100,color: Colors.grey,),
Container(height: 100,color: Colors.grey,),
Container(height: 100,color: Colors.grey,),
Container(height: 100,color: Colors.grey,),
Container(height: 100,color: Colors.grey,),
]);
ListView
将 widget 展示为一个可滚动的列表。
ListView({
Key key,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller,
bool primary,
ScrollPhysics physics,
bool shrinkWrap = false,
EdgeInsetsGeometry padding,
this.itemExtent,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
double cacheExtent,
List children = const [],
int semanticChildCount,
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
})
示例
ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: 10,
itemBuilder: (BuildContext context, int index) {
var entries = ["0","1","2","3","4","5","6","7","8","9"];
var colorCodes = [0,100,200,300,400,500,600,700,800,900];
return Container(
height: 100,
color: Colors.amber[colorCodes[index]],
child: Center(child: Text('Entry ${entries[index]}')),
);
})
SingleChildScrollView
可以容纳一个子控件的ScrollView
SingleChildScrollView({
Key key,
this.scrollDirection = Axis.vertical,
this.reverse = false,
this.padding,
bool primary,
this.physics,
this.controller,
this.child,
this.dragStartBehavior = DragStartBehavior.start,
})
Material widgets
Card
将相关信息整理到一个有圆角和阴影的盒子中,设置子控件的圆角。
Card({
Key key,
this.color,
this.elevation,
this.shape,
this.borderOnForeground = true,
this.margin,
this.clipBehavior,
this.child,
this.semanticContainer = true,
})
ListTile
将最多三行的文本、可选的导语以及后面的图标组织在一行中。
ListTile({
Key key,
this.leading,
this.title,
this.subtitle,
this.trailing,
this.isThreeLine = false,
this.dense,
this.contentPadding,
this.enabled = true,
this.onTap,
this.onLongPress,
this.selected = false,
})
其他
AspectRatio 按比例显示
AspectRatio(
child: Image. asset(
"images/example.jpg",
fit: BoxFit.cover,
),
aspectRatio: 3 / 2, // 宽 比 高
)