Row和Column分别是Flutter中的水平和垂直布局,它们都是MultiChildRenderObjectWidget,所以它们都是可以渲染多个孩子的控件,而它们是如何渲染孩子的大小和位置的则是有renderObject定义的。它们的继承关系图如下:
Row、Column的布局特性和MainAxisAlignment(主轴)和CrossAxisAlignment(交叉轴)有关。主轴是与当前控件方向一致的轴,而交叉轴就是与当前控件方向垂直方向的轴。主轴和交叉轴是相对于的,它们主要用于控制Row,Column的子控件排列位置。因此,在Row中,MainAxisAlignment的方向是水平的,默认的起始位置在左边,排列方向是从左至右;而CrossAxisAlignment的方向则是垂直的,默认的起始位置在中间,排列方向是从上到下。
相对的,在Column中,MainAxisAlignment的方向是垂直的,默认起始位置在上边,排列方向是从上至下;CrossAxisAlignment的方向则是水平的,默认的起始位置在中间,排列方向是从左到右。另外,textDirection和verticalDirection可以分别改变水平和垂直方向的起始位置和排列方向。
MainAxisAlignment的值:
enum MainAxisAlignment {
//将子控件放在主轴的开始位置
start,
//将子控件放在主轴的结束位置
end,
//将子控件放在主轴的中间位置
center,
//将主轴空白位置进行均分,排列子元素,手尾没有空隙
spaceBetween,
//将主轴空白区域均分,使中间各个子控件间距相等,首尾子控件间距为中间子控件间距的一半
spaceAround,
//将主轴空白区域均分,使各个子控件间距相等
spaceEvenly,
}
CrossAxisAlignment取值:
enum CrossAxisAlignment {
//将子控件放在交叉轴的起始位置
start,
//将子控件放在交叉轴的结束位置
end,
//将子控件放在交叉轴的中间位置
center,
//使子控件填满交叉轴
stretch,
//将子控件放在交叉轴的上,并且与基线相匹配(不常用)
baseline,
}
textDirection取值:
enum TextDirection {
//从右到左排列
rtl,
//从左到右排列
ltr,
}
VerticalDirection取值
enum VerticalDirection {
//从上到下
up,
//从下到上
down,
}
为了实例说明的方便,这里专门封装一个box控件来说明Row和Column布局特性。
class Box extends StatelessWidget {
String index;
double boxSize = 100.0;
Box(String index) {
this.index = index;
}
@override
Widget build(BuildContext context) {
return Container(
width: boxSize,
height: boxSize,
alignment: Alignment.center,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.orangeAccent, Colors.orange, Colors.deepOrange]
)
),
child: Text(
index,
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold
),
),
);
}
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 200.0,
child: Row(
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}
可以看出来,Row的默认起始位置在左边,排列方向是从左到右。也就是:
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
textDirection: TextDirection.ltr,
verticalDirection: VerticalDirection.down,
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 200.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.ltr,
verticalDirection: VerticalDirection.down,
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}
为了看出verticalDirection: VerticalDirection.up的效果,故意把crossAxisAlignment设置为了CrossAxisAlignment.start
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 200.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.rtl,
verticalDirection: VerticalDirection.up,
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 200.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.ltr,
verticalDirection: VerticalDirection.up,
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 200.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.rtl,
verticalDirection: VerticalDirection.down,
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 200.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
textDirection: TextDirection.ltr,
verticalDirection: VerticalDirection.down,
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 200.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
textDirection: TextDirection.rtl,
verticalDirection: VerticalDirection.down,
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 200.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
textDirection: TextDirection.ltr,
verticalDirection: VerticalDirection.down,
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 600.0,
width: 400.0,
child: Column(
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
textDirection: TextDirection.ltr,
verticalDirection: VerticalDirection.down,
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 600.0,
width: 400.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.ltr,
verticalDirection: VerticalDirection.down,
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 600.0,
width: 400.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.rtl,
verticalDirection: VerticalDirection.up,
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 600.0,
width: 400.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.ltr,
verticalDirection: VerticalDirection.up,
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 600.0,
width: 400.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.rtl,
verticalDirection: VerticalDirection.down,
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 600.0,
width: 400.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
textDirection: TextDirection.ltr,
verticalDirection: VerticalDirection.down,
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 600.0,
width: 400.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
textDirection: TextDirection.ltr,
verticalDirection: VerticalDirection.up,
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}
class _MyHomePageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
color: Colors.green,
height: 600.0,
width: 400.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
textDirection: TextDirection.ltr,
verticalDirection: VerticalDirection.down,
children: [
Box("1"),
Box("2"),
Box("3"),
Box("4")
],
),
),
);
}
}