对于线性的布局排列,Android中使用的是LinearLayout,至于是横向还是纵向,则是通过orientation属性来指定的,orientation=vertical表示纵向线性,orientation=horizontal表示横向线性。在Flutter中,将这两种线性布局分别用Column和Row来表示。
Column:orientation=vertical
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 1void main(){
2 runApp(MaterialApp(
3 home: MaterialHome(),
4 ));
5}
6
7class MaterialHome extends StatelessWidget{
8 @override
9 Widget build(BuildContext context) {
10 return Scaffold(
11 appBar: AppBar(
12 title: Text("Row_column"),
13 ),
14 body: Column(
15 children: <Widget>[
16 Image.asset("images/pic1.jpg"),
17 Image.asset("images/pic2.jpg"),
18 Image.asset("images/pic3.jpg")
19 ],
20 ),
21 );
22 }
23}
24
运行效果如下:
这段代码需要注意下,由于我们使用了asset资源,所以我们在lib的平级目录新建一个images目录,然后将图片放置到这个目录下,如图所示:
最后还需要在.yaml文件中进行相关配置:
现在我想让图片居中,该如何实现?这里就需要用到一个属性:mainAxisAlignment,它的可选值如下:
- start
- center
- end
- spaceBetween
- spaceEvenly
- spaceAround
实现居中,自然而然想到要使用center:
1
2
3
4
5
6
7
8
9 1body: Column(
2 mainAxisAlignment: MainAxisAlignment.center,
3 children: <Widget>[
4 Image.asset("images/pic1.jpg"),
5 Image.asset("images/pic2.jpg"),
6 Image.asset("images/pic3.jpg")
7 ],
8),
9
至于end,就更好理解了:
这三个属性,可以看做是一类,即子Widget之间没有空隙,它们作为一个整体放置到靠上、居中、靠下的不同地方。而space开头的属性值可以看做一个类别,子Widget之间有空隙:
1
2
3
4
5
6
7
8
9 1body: Column(
2 mainAxisAlignment: MainAxisAlignment.spaceBetween,
3 children: <Widget>[
4 Image.asset("images/pic1.jpg"),
5 Image.asset("images/pic2.jpg"),
6 Image.asset("images/pic3.jpg")
7 ],
8 ),
9
1
2
3
4
5
6
7
8
9 1body: Column(
2 mainAxisAlignment: MainAxisAlignment.spaceEvenly,
3 children: <Widget>[
4 Image.asset("images/pic1.jpg"),
5 Image.asset("images/pic2.jpg"),
6 Image.asset("images/pic3.jpg")
7 ],
8),
9
1
2
3
4
5
6
7
8
9 1body: Column(
2 mainAxisAlignment: MainAxisAlignment.spaceAround,
3 children: <Widget>[
4 Image.asset("images/pic1.jpg"),
5 Image.asset("images/pic2.jpg"),
6 Image.asset("images/pic3.jpg")
7 ],
8 ),
9
我们可以借助于LinearLayout的weight属性来帮助理解:
-
spaceBetween
1
2
3
4
5
6
7
8
9
10
11 1<LinearLayout
2 orientation="vertical"
3 ...>
4
5 <ImageView/>
6 <View android:layout_weight="1"/>
7 <ImageView/>
8 <View android:layout_weight="1"/>
9 <ImageView/>
10</LinearLayout>
11
1
2 1* spaceEvenly
2
1
2
3
4
5
6
7
8
9
10
11
12 1<LinearLayout
2 orientation="vertical"
3 ...>
4 <View android:layout_weight="1"/>
5 <ImageView/>
6 <View android:layout_weight="1"/>
7 <ImageView/>
8 <View android:layout_weight="1"/>
9 <ImageView/>
10 <View android:layout_weight="1"/>
11</LinearLayout>
12
1
2 1* spaceAround
2
1
2
3
4
5
6
7
8
9
10
11
12 1<LinearLayout
2 orientation="vertical"
3 ...>
4 <View android:layout_weight="1"/>
5 <ImageView/>
6 <View android:layout_weight="2"/>
7 <ImageView/>
8 <View android:layout_weight="2"/>
9 <ImageView/>
10 <View android:layout_weight="1"/>
11</LinearLayout>
12
当然,要想mainAxisAlignment有效,则需要将mainAxisSize指定为MainAxisSize.max(默认值)。对于mainAxisSize属性,它的可选值为:
- MainAxisSize.max, 表示尽可能多的占据垂直方向的空间,可以类比成match_parent
- MainAxisSize.min,表示尽可能少的占据垂直方向的空间,这种情况下,Column的高度等于子Widget的高度,那么mainAxisAlignment属性指定为任何值都不起作用,可以类比成wrap_content
下面介绍Column的另外两个属性: crossAxisAlignment和textDirection
textDirection的可选值为:
- TextDirection.ltr:表示水平方向的排列方式为从左到右
- TextDirection.rtl:表示水平方向的排列方式为从右到左
crossAxisAlignment,表示子Widget在水平方向上的对齐方式,它的可选值为:
- start:ltr时,左对齐;rtl,右对齐
- end:ltr时,右对齐;rtl,左对齐
- center:居中
- stretch:填充
- baseline: 暂时我也不清楚用法
看下面的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 1body: Column(
2 mainAxisAlignment: MainAxisAlignment.center,
3 textDirection: TextDirection.ltr,
4 crossAxisAlignment: CrossAxisAlignment.start,
5
6 children: <Widget>[
7 Container(
8 decoration: BoxDecoration(color: Colors.red),
9 height: 60,
10 width: 60,
11 ),
12 Container(
13 decoration: BoxDecoration(color: Colors.yellow),
14 height: 60,
15 width: 100,
16 ),
17 Container(
18 decoration: BoxDecoration(color: Colors.blue),
19 height: 60,
20 width: 60,
21 )
22 ],
23 ),
24
效果图如下:
改为CrossAxisAlignment.end:
改为CrossAxisAlignment.center:
改为CrossAxisAlignment.stretch:
介绍的最后一个属性为verticalDirection,可选值为: – VerticalDirection.down:表示子Widget从上往下排列,默认值 – VerticalDirection.up:表示子Widget从下往上排列,在上例中红色框就会在下面,蓝色跑到了最上面
- Expanded
对于Android中的LinearLayout,有一个属性我们不得不提:layout_weight。那么Flutter中有没有类似Widget呢?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 1body: Column(
2 children: <Widget>[
3 Container(
4 decoration: BoxDecoration(color: Colors.red),
5 height: 60,
6 width: 60,
7 ),
8 Expanded(
9 flex: 1,
10 child: Container(
11 decoration: BoxDecoration(color: Colors.yellow),
12 width: 100,
13 )),
14 Container(
15 decoration: BoxDecoration(color: Colors.blue),
16 height: 60,
17 width: 60,
18 )
19
20 ],
21),
22
没错,就是这个Expanded,运行效果如下:
那么如何指定对应的权重值呢?Expanded中有个属性叫做flex,默认为1,通过它就可以指定相应的权重值。
- Row orientation=horizontal
大部分属性的使用都和Column类似,只不过方向不同而已。只有一个地方需要注意: 在Column中,crossAxisAlignment的参照物是textDirection,而在Row中 crossAxisAlignment参照物变成了verticalDirection,换句话说就是crossAxisAlignment要和verticalDirection一起使用才能决定子Widget在垂直方向的对齐方式。其他的属性就不再赘述了,大家可以对照Column进行理解。当然,Expanded同样可以在Row中使用。