W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
所謂線性布局,即指沿水平或垂直方向排布子組件。Flutter 中通過Row
和Column
來實(shí)現(xiàn)線性布局,類似于 Android 中的LinearLayout
控件。Row
和Column
都繼承自Flex
,我們將在彈性布局一節(jié)中詳細(xì)介紹Flex
。
對于線性布局,有主軸和縱軸之分,如果布局是沿水平方向,那么主軸就是指水平方向,而縱軸即垂直方向;如果布局沿垂直方向,那么主軸就是指垂直方向,而縱軸就是水平方向。在線性布局中,有兩個定義對齊方式的枚舉類MainAxisAlignment
和CrossAxisAlignment
,分別代表主軸對齊和縱軸對齊。
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
:表示水平方向子組件的布局順序(是從左往右還是從右往左),默認(rèn)為系統(tǒng)當(dāng)前Locale環(huán)境的文本方向(如中文、英語都是從左往右,而阿拉伯語是從右往左)。mainAxisSize
:表示Row
在主軸(水平)方向占用的空間,默認(rèn)是MainAxisSize.max
,表示盡可能多的占用水平方向的空間,此時無論子widgets實(shí)際占用多少水平空間,Row
的寬度始終等于水平方向的最大寬度;而MainAxisSize.min
表示盡可能少的占用水平空間,當(dāng)子組件沒有占滿水平剩余空間,則Row
的實(shí)際寬度等于所有子組件占用的的水平空間;mainAxisAlignment
:表示子組件在Row
所占用的水平空間內(nèi)對齊方式,如果mainAxisSize
值為MainAxisSize.min
,則此屬性無意義,因?yàn)樽咏M件的寬度等于Row
的寬度。只有當(dāng)mainAxisSize
的值為MainAxisSize.max
時,此屬性才有意義,MainAxisAlignment.start
表示沿textDirection
的初始方向?qū)R,如textDirection
取值為TextDirection.ltr
時,則MainAxisAlignment.start
表示左對齊,textDirection
取值為TextDirection.rtl
時表示從右對齊。而MainAxisAlignment.end
和MainAxisAlignment.start
正好相反;MainAxisAlignment.center
表示居中對齊。讀者可以這么理解:textDirection
是mainAxisAlignment
的參考系。verticalDirection
:表示Row
縱軸(垂直)的對齊方向,默認(rèn)是VerticalDirection.down
,表示從上到下。crossAxisAlignment
:表示子組件在縱軸方向的對齊方式,Row
的高度等于子組件中最高的子元素高度,它的取值和MainAxisAlignment
一樣(包含start
、end
、 center
三個值),不同的是crossAxisAlignment
的參考系是verticalDirection
,即verticalDirection
值為VerticalDirection.down
時crossAxisAlignment.start
指頂部對齊,verticalDirection
值為VerticalDirection.up
時,crossAxisAlignment.start
指底部對齊;而crossAxisAlignment.end
和crossAxisAlignment.start
正好相反;children
:子組件數(shù)組。請閱讀下面代碼,先想象一下運(yùn)行的結(jié)果:
Column(
//測試Row對齊方式,排除Column默認(rèn)居中對齊的干擾
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,
children: <Widget>[
Text(" hello world "),
Text(" I am Jack "),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
textDirection: TextDirection.rtl,
children: <Widget>[
Text(" hello world "),
Text(" I am Jack "),
],
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
verticalDirection: VerticalDirection.up,
children: <Widget>[
Text(" hello world ", style: TextStyle(fontSize: 30.0),),
Text(" I am Jack "),
],
),
],
);
實(shí)際運(yùn)行結(jié)果如圖4-1所示:
解釋:第一個Row
很簡單,默認(rèn)為居中對齊;第二個Row
,由于mainAxisSize
值為MainAxisSize.min
,Row
的寬度等于兩個Text
的寬度和,所以對齊是無意義的,所以會從左往右顯示;第三個Row
設(shè)置textDirection
值為TextDirection.rtl
,所以子組件會從右向左的順序排列,而此時MainAxisAlignment.end
表示左對齊,所以最終顯示結(jié)果就是圖中第三行的樣子;第四個Row測試的是縱軸的對齊方式,由于兩個子Text字體不一樣,所以其高度也不同,我們指定了verticalDirection
值為VerticalDirection.up
,即從低向頂排列,而此時crossAxisAlignment
值為CrossAxisAlignment.start
表示底對齊。
Column
可以在垂直方向排列其子組件。參數(shù)和Row
一樣,不同的是布局方向?yàn)榇怪?,主軸縱軸正好相反,讀者可類比Row
來理解,下面看一個例子:
import 'package:flutter/material.dart';
class CenterColumnRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text("hi"),
Text("world"),
],
);
}
}
運(yùn)行效果如圖4-2所示:
解釋:
Column
的mainAxisSize
,所以使用默認(rèn)值MainAxisSize.max
,則Column
會在垂直方向占用盡可能多的空間,此例中為屏幕高度。crossAxisAlignment
屬性為CrossAxisAlignment.center
,那么子項在Column
縱軸方向(此時為水平方向)會居中對齊。注意,在水平方向?qū)R是有邊界的,總寬度為Column
占用空間的實(shí)際寬度,而實(shí)際的寬度取決于子項中寬度最大的 Widget。在本例中,Column
有兩個子 Widget,而顯示“world”的Text
寬度最大,所以Column
的實(shí)際寬度則為Text("world")
的寬度,所以居中對齊后Text("hi")
會顯示在Text("world")
的中間部分。
實(shí)際上,Row
和Column
都只會在主軸方向占用盡可能大的空間,而縱軸的長度則取決于他們最大子元素的長度。如果我們想讓本例中的兩個文本控件在整個手機(jī)屏幕中間對齊,我們有兩種方法:
Column
的寬度指定為屏幕寬度;這很簡單,我們可以通過ConstrainedBox
或SizedBox
(我們將在后面章節(jié)中專門介紹這兩個 Widget)來強(qiáng)制更改寬度限制,例如: ConstrainedBox(
constraints: BoxConstraints(minWidth: double.infinity),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text("hi"),
Text("world"),
],
),
);
將minWidth
設(shè)為double.infinity
,可以使寬度占用盡可能多的空間。
Center
Widget;我們將在后面章節(jié)中介紹。
如果Row
里面嵌套Row
,或者Column
里面再嵌套Column
,那么只有最外面的Row
或Column
會占用盡可能大的空間,里面Row
或Column
所占用的空間為實(shí)際大小,下面以Column
為例說明:
Container(
color: Colors.green,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max, //有效,外層Colum高度為整個屏幕
children: <Widget>[
Container(
color: Colors.red,
child: Column(
mainAxisSize: MainAxisSize.max,//無效,內(nèi)層Colum高度為實(shí)際高度
children: <Widget>[
Text("hello world "),
Text("I am Jack "),
],
),
)
],
),
),
);
運(yùn)行效果如圖4-3所示:
如果要讓里面的Column
占滿外部Column
,可以使用Expanded
組件:
Expanded(
child: Container(
color: Colors.red,
child: Column(
mainAxisAlignment: MainAxisAlignment.center, //垂直方向居中對齊
children: <Widget>[
Text("hello world "),
Text("I am Jack "),
],
),
),
)
運(yùn)行效果如圖4-4所示:
我們將在介紹彈性布局時詳細(xì)介紹 Expanded。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: