線性布局Row和Column
所謂線性布局契耿,即指沿水平或垂直方向排布子Widget。Flutter中通過(guò)Row和Column來(lái)實(shí)現(xiàn)線性布局系洛,類(lèi)似于Android中的LinearLayout控件俊性。Row和Column都繼承自Flex,我們將在彈性布局一節(jié)中詳細(xì)介紹Flex描扯。
主軸和縱軸
對(duì)于線性布局定页,有主軸和縱軸之分,如果布局是沿水平方绽诚,那么主軸就指是水平方向拯勉,而縱軸即垂直方向;如果布局沿垂直方向憔购,那么主軸就是指垂直方向,而縱軸就是水平方向岔帽。在線性布局中玫鸟,有兩個(gè)定義對(duì)齊方式的枚舉類(lèi)MainAxisAlignment和CrossAxisAlignment,分別代表主軸對(duì)齊和縱軸對(duì)齊犀勒。
Row
Row可以在水平方向排列其子widget屎飘。定義如下:
Row({
...
TextDirection textDirection,
MainAxisSize mainAxisSize = MainAxisSize.max,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
VerticalDirection verticalDirection = VerticalDirection.down,
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
List<Widget> children = const <Widget>[],
})
textDirection:表示水平方向子widget的布局順序(是從左往右還是從右往左)妥曲,默認(rèn)為系統(tǒng)當(dāng)前Locale環(huán)境的文本方向(如中文、英語(yǔ)都是從左往右钦购,而阿拉伯語(yǔ)是從右往左)檐盟。
mainAxisSize:表示Row在主軸(水平)方向占用的空間,默認(rèn)是MainAxisSize.max押桃,表示盡可能多的占用水平方向的空間葵萎,此時(shí)無(wú)論子widgets實(shí)際占用多少水平空間,Row的寬度始終等于水平方向的最大寬度唱凯;而MainAxisSize.min表示盡可能少的占用水平空間羡忘,當(dāng)子widgets沒(méi)有占滿(mǎn)水平剩余空間,則Row的實(shí)際寬度等于所有子widgets占用的的水平空間磕昼;
mainAxisAlignment:表示子Widgets在Row所占用的水平空間內(nèi)對(duì)齊方式卷雕,如果mainAxisSize值為MainAxisSize.min,則此屬性無(wú)意義票从,因?yàn)樽觲idgets的寬度等于Row的寬度漫雕。只有當(dāng)mainAxisSize的值為MainAxisSize.max時(shí),此屬性才有意義
MainAxisAlignment.start表示沿textDirection的初始方向?qū)R峰鄙,如textDirection取值為T(mén)extDirection.ltr時(shí)浸间,則MainAxisAlignment.start表示左對(duì)齊,textDirection取值為T(mén)extDirection.rtl時(shí)表示從右對(duì)齊先馆。而MainAxisAlignment.end和MainAxisAlignment.start正好相反发框;MainAxisAlignment.center表示居中對(duì)齊。讀者可以這么理解:textDirection是mainAxisAlignment的參考系煤墙。
verticalDirection:表示Row縱軸(垂直)的對(duì)齊方向梅惯,默認(rèn)是VerticalDirection.down,表示從上到下仿野。
crossAxisAlignment:表示子Widgets在縱軸方向的對(duì)齊方式铣减,Row的高度等于子Widgets中最高的子元素高度,它的取值和MainAxisAlignment一樣(包含start脚作、end葫哗、 center三個(gè)值),不同的是crossAxisAlignment的參考系是verticalDirection球涛,即verticalDirection值為VerticalDirection.down時(shí)crossAxisAlignment.start指頂部對(duì)齊劣针,verticalDirection值為VerticalDirection.up時(shí),crossAxisAlignment.start指底部對(duì)齊亿扁;而crossAxisAlignment.end和crossAxisAlignment.start正好相反捺典;
children :子Widgets數(shù)組。
示例:
Widget _body(){
return Column(
//測(cè)試Row對(duì)齊方式从祝,排除Column默認(rèn)居中對(duì)齊的干擾
crossAxisAlignment: CrossAxisAlignment.start,//垂直方向 向左靠齊
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,//主軸居中
children: <Widget>[
Text(" hello world "),
Text(" I am Jack "),
],
),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
//襟己,由于mainAxisSize值為MainAxisSize.min引谜,Row的寬度等于兩個(gè)Text的寬度和,
// 所以對(duì)齊是無(wú)意義的擎浴,所以會(huì)從左往右顯示
children: <Widget>[
Text(" hello world "),
Text(" I am Jack "),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
textDirection: TextDirection.rtl,
//Row設(shè)置textDirection值為T(mén)extDirection.rtl员咽,
// 所以子widget會(huì)從右向左的順序排列,而此時(shí)MainAxisAlignment.end表示左對(duì)齊
children: <Widget>[
Text(" hello world "),
Text(" I am Jack "),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
verticalDirection: VerticalDirection.up,
//由于兩個(gè)子Text字體不一樣贮预,所以其高度也不同贝室,我們指定了verticalDirection值為VerticalDirection.up,
// 即從低向頂排列萌狂,而此時(shí)crossAxisAlignment值為CrossAxisAlignment.start表示底對(duì)齊
children: <Widget>[
Text(" hello world ", style: TextStyle(fontSize: 30.0),),
Text(" I am Jack "),
],
),
],
);
}
解釋?zhuān)旱谝粋€(gè)Row很簡(jiǎn)單档玻,默認(rèn)為居中對(duì)齊;第二個(gè)Row茫藏,由于mainAxisSize值為MainAxisSize.min误趴,Row的寬度等于兩個(gè)Text的寬度和,所以對(duì)齊是無(wú)意義的务傲,所以會(huì)從左往右顯示凉当;第三個(gè)Row設(shè)置textDirection值為T(mén)extDirection.rtl,所以子widget會(huì)從右向左的順序排列售葡,而此時(shí)MainAxisAlignment.end表示左對(duì)齊看杭,所以最終顯示結(jié)果就是圖中第三行的樣子;第四個(gè)Row測(cè)試的是縱軸的對(duì)齊方式挟伙,由于兩個(gè)子Text字體不一樣楼雹,所以其高度也不同,我們指定了verticalDirection值為VerticalDirection.up尖阔,即從低向頂排列贮缅,而此時(shí)crossAxisAlignment值為CrossAxisAlignment.start表示底對(duì)齊。
Column
Column可以在垂直方向排列其子widget介却。參數(shù)和Row一樣谴供,不同的是布局方向?yàn)榇怪保鬏S縱軸正好相反齿坷,讀者可類(lèi)比Row來(lái)理解桂肌,在此不再贅述。
特殊情況
如果Row里面嵌套R(shí)ow永淌,或者Column里面再嵌套Column崎场,那么只有對(duì)最外面的Row或Column會(huì)占用盡可能大的空間,里面Row或Column所占用的空間為實(shí)際大小遂蛀,下面以Column為例說(shuō)明:
Widget _body(){
return Container(
color: Colors.green,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max, //有效照雁,外層Colum高度為整個(gè)屏幕
children: <Widget>[
Container(
color: Colors.red,
child: Column(
mainAxisSize: MainAxisSize.max,//無(wú)效歉甚,內(nèi)層Colum高度為實(shí)際高度
children: <Widget>[
Text("hello world "),
Text("I am Jack "),
],
),
)
],
),
),
);
}