目录
1.Table
2.Wrap
3.ListBody
4.CustomMultiChildLayout
5.LayoutBuilder
6.ListView
7.Expanded
一个将子部件进行表格布局的部件
文档
border → TableBorder:边框格式
columnWidths → Map
defaultColumnWidth → TableColumnWidth:默认列宽
textBaseline → TextBaseline:当TableCellVerticalAlignment为baseline时 使用的文本基线
textDirection → TextDirection://列排列顺序
children → List
示例:
class MyTable extends StatelessWidget {
@override
Widget build(BuildContext context) {
List list = getMainList();
return Table(
border: TableBorder.all(width:3.0,color: Colors.red),//边框格式
defaultColumnWidth: IntrinsicColumnWidth(flex: 20.0), //默认列宽
columnWidths: const {
0: IntrinsicColumnWidth(flex: 20.0),//第0列宽度
1: IntrinsicColumnWidth(flex: 60.0)//第一列宽度
},
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
textBaseline:
TextBaseline.alphabetic, //当TableCellVerticalAlignment为baseline时起作用
textDirection: TextDirection.rtl, //列排列顺序
children: list,
);
}
//获取子控件列表
List getMainList() {
List list = new List();
for (var i = 0; i < 10; i++) {
list.add(TableRow(children: [
TableCell(
child: Container(
color: Colors.amber,
child: Text(i.toString()),
),
),
TableCell(
child: Container(
color: Colors.amber,
child: Text(i.toString()),
),
),
]));
}
return list;
}
}
一个将子部件垂直或水平摆放的部件
当主轴方向控件不足时将换行或换列
文档
alignment → WrapAlignment:主轴方向 子部件排列方式
crossAxisAlignment → WrapCrossAlignment:每一行或列 子部件们的对齐方式
direction → Axis:主轴方向
runAlignment → WrapAlignment:非主轴方向子部件排列方式
runSpacing → double:非主轴方向间距
spacing → double:主轴方向间距
textDirection → TextDirection:横向排列顺序
verticalDirection → VerticalDirection:纵向排列顺序
children → List
示例
Wrap(
alignment: WrapAlignment.center,//主轴方向排列方式
crossAxisAlignment:WrapCrossAlignment.center,//每一行或列 子部件们的对齐方式
direction: Axis.horizontal,//主轴方向
runAlignment: WrapAlignment.center,//非主轴方向的排列方式
runSpacing: 10.0,//非主轴方向间隔
spacing: 10.0,//主轴方向间隔
textDirection: TextDirection.rtl,//横向排列顺序
verticalDirection: VerticalDirection.down,//垂直排列顺序
children: [
Container(
width: 80.0,
height: 80.0,
color: Colors.red,
child: Text("1",style: TextStyle(color:Colors.white),),
),
Container(
width: 80.0,
height: 100.0,
color: Colors.red,
child: Text("2",style: TextStyle(color:Colors.white),),
),
Container(
width: 80.0,
height: 80.0,
color: Colors.red,
child: Text("3",style: TextStyle(color:Colors.white),),
),
Container(
width: 80.0,
height: 80.0,
color: Colors.red,
child: Text("4",style: TextStyle(color:Colors.white),),
),
Container(
width: 80.0,
height: 80.0,
color: Colors.red,
child: Text("5",style: TextStyle(color:Colors.white),),
),
Container(
width: 80.0,
height: 80.0,
color: Colors.red,
child: Text("6",style: TextStyle(color:Colors.white),),
),
Container(
width: 80.0,
height: 80.0,
color: Colors.red,
child: Text("7",style: TextStyle(color:Colors.white),),
),
Container(
width: 80.0,
height: 80.0,
color: Colors.red,
child: Text("8",style: TextStyle(color:Colors.white),),
),
],
);
文档
这个小部件很少直接使用。 使用ListView或Column替代
一个可以调整多个子部件位置的部件
当多个小部件的大小和位置之间存在复杂关系时,CustomMultiChildLayout是合适的。
要控制单个子项的布局,CustomSingleChildLayout更合适。
对于简单的情况,例如将小部件与一个或另一个边缘对齐,Stack小部件更合适。
必须将每个子项包装在LayoutId小部件中,以标识委托的小部件。
文档
delegate → MultiChildLayoutDelegate:子部件摆放方式
children → List
class MyCustomMultiChildLayout extends StatelessWidget{
@override
Widget build(BuildContext context) {
return
CustomMultiChildLayout(
delegate: Delegate(),
children: [
LayoutId(
id: _Slot.leader,
child:Container(
width: 100,
height: 100,
color: Colors.green,
),
),
LayoutId(
id: _Slot.follower,
child:Container(
width: 100,
height: 100,
color: Colors.red,
),
),
],
);
}
}
enum _Slot {
leader,
follower,
}
class Delegate extends MultiChildLayoutDelegate{
@override
void performLayout(Size size) {
Size leaderSize = Size.zero;
if (hasChild(_Slot.leader)) {
leaderSize = layoutChild(_Slot.leader, BoxConstraints.loose(size));
positionChild(_Slot.leader, Offset.zero);
}
if (hasChild(_Slot.follower)) {
layoutChild(_Slot.follower, BoxConstraints.tight(leaderSize));
positionChild(_Slot.follower, Offset(leaderSize.width,
leaderSize.height));
}
}
@override
bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) {
return false;
}
}
构建一个可以依赖父部件大小的窗口部件树
文档
builder → LayoutWidgetBuilder:构造部件树方法。 构建器不得返回null。
LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
//这里可以根据constraints做一些判断以返回不同情况的子部件
return Column(
children: [
Container(
width: 100.0,
height: 100.0,
color: Colors.red,
child: Text("1"),
),
Container(
width: 100.0,
height: 100.0,
color: Colors.blue,
child: Text("1"),
),
Container(
width: 100.0,
height: 100.0,
color: Colors.yellow,
child: Text("1"),
),
],
);
},
);
一个线性排列子部件的可滚动部件
文档
构建ListView有四个选项:
默认构造函数采用子类的显式List
ListView.builder构造函数采用IndexedWidgetBuilder,它根据需要构建子项。此构造函数适用于具有大量(或无限)子项数的列表视图,此方法仅当子项可见时调用构建器。
ListView.separated构造函数采用两个IndexedWidgetBuilders:itemBuilder按需构建子项,而separatorBuilder类似地构建出现在子项之间的子项。此构造函数适用于具有固定数量子项的列表视图。
ListView.custom构造函数采用SliverChildDelegate,它提供了自定义子模型的其他方面的功能。例如,SliverChildDelegate可以控制用于估计实际上不可见的子项大小的算法。
ListView(
scrollDirection: Axis.horizontal,//滚动方向
reverse: false,//是否翻转
children: [
Container(
width: 100,
color: Colors.red,
alignment: Alignment.center,
child: Text("1",style: TextStyle(color: Colors.white),),
),
Container(
width: 100,
color: Colors.blue,
alignment: Alignment.center,
child: Text("2",style: TextStyle(color: Colors.white),),
),
Container(
width: 100,
color: Colors.red,
alignment: Alignment.center,
child: Text("3",style: TextStyle(color: Colors.white),),
),
Container(
width: 100,
color: Colors.blue,
alignment: Alignment.center,
child: Text("4",style: TextStyle(color: Colors.white),),
),
Container(
width: 100,
color: Colors.red,
alignment: Alignment.center,
child: Text("5",style: TextStyle(color: Colors.white),),
),
Container(
width: 100,
color: Colors.blue,
alignment: Alignment.center,
child: Text("6",style: TextStyle(color: Colors.white),),
),
],
);
ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Container(
color: Colors.blue,
alignment: Alignment.center,
child: Text(
"1",
style: TextStyle(color: Colors.white),
),
);
});
ListView.separated(
itemCount: 20,
separatorBuilder: (BuildContext context, int index) {//分隔线
return Container(
color: Colors.white,
height: 2,
);
},
itemBuilder: (BuildContext context, int index) {//主item
return Container(
color: Colors.blue,
alignment: Alignment.center,
child: Text(
"2",
style: TextStyle(color: Colors.white),
),
);
});
ListView.custom(
childrenDelegate:
SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(
color: Colors.blue,
alignment: Alignment.center,
child: Text(
"1",
style: TextStyle(color: Colors.white),
),
);
}),
);
一个使Row,Column或Flex的子部件填充剩余空间的部件
文档
使用Expanded部件可以使子项展开以填充主轴中的可用空间(例如,水平为行,或垂直为列)。 如果扩展了多个子节点,则根据弹性因子将可用空间划分为多个子节点。
扩展窗口小部件必须是行,列或Flex的后代,并且从部件到其封闭的行,列或Flex的路径必须仅包含StatelessWidgets或StatefulWidgets(不是其他类型的窗口小部件,如RenderObjectWidgets)。
flex → int:弹性因子
child → Widget:子部件
Row(
children: [
Expanded(
flex: 2,
child: Container(color:Colors.blue,child: Text("1",style: TextStyle(color: Colors.white))),
),
Expanded(
child: Container(color:Colors.red,child: Text("2",style: TextStyle(color: Colors.white))),
),
Expanded(
child: Container(color:Colors.amber,child: Text("3",style: TextStyle(color: Colors.white))),
),
Expanded(
child: Container(color:Colors.deepPurple,child: Text("4",style: TextStyle(color: Colors.white))),
),
Expanded(
child: Container(color:Colors.green,child: Text("5",style: TextStyle(color: Colors.white))),
),
],
);