1.Row
線性布局,將children排成一行,主軸為水平方向,交叉軸為垂直方向。
- textDirection:表示水平方向子widget的布局順序是從左往右還是從右往左。
- mainAxisSize:主軸方向的占用空間。默認(rèn)是MainAxisSize.max,表示盡可能多的占用水平方向的空間,此時(shí)無論子widgets實(shí)際占用多少水平空間,Row的寬度始終等于水平方向的最大寬度;而MainAxisSize.min表示盡可能少的占用水平空間,當(dāng)子widgets沒有占滿水平剩余空間,則Row的實(shí)際寬度等于所有子widgets占用的的水平空間;
- mainAxisAlignment:主軸對(duì)齊方式,如果mainAxisSize值為MainAxisSize.min ,則此屬性無意義,因?yàn)樽觲idgets的寬度等于Row的寬度。只有當(dāng)mainAxisSize的值為MainAxisSize.max時(shí),此屬性才有意義。textDirection是mainAxisAlignment的參考系,textDirection取值為TextDirection.ltr時(shí),則MainAxisAlignment.start表示左對(duì)齊,textDirection取值為TextDirection.rtl時(shí)表示從右對(duì)齊。
- crossAxisAlignment:交叉軸對(duì)齊方式,Row的高度等于子Widgets中最高的子元素高度。crossAxisAlignment的參考系是verticalDirection,即verticalDirection值為VerticalDirection.down時(shí)crossAxisAlignment.start指頂部對(duì)齊,verticalDirection值為VerticalDirection.up時(shí),crossAxisAlignment.start指底部對(duì)齊;而crossAxisAlignment.end和crossAxisAlignment.start正好相反;
- children :子widget數(shù)組
2.Column
Column可以在垂直方向排列其子widget。參數(shù)和Row一樣,不同的是布局方向?yàn)榇怪保鬏S縱軸正好相反
如果Row里面嵌套R(shí)ow,或者Column里面再嵌套Column,那么只有對(duì)最外面的Row或Column會(huì)占用盡可能大的空間,里面Row或Column所占用的空間為實(shí)際大小
3.Stack
可以允許其子widget簡(jiǎn)單的堆疊在一起,相當(dāng)于Android中的FrameLayout,
- alignment:此參數(shù)決定如何去對(duì)齊沒有定位(沒有使用Positioned)或部分定位的子widget。所謂部分定位,在這里特指沒有在某一個(gè)軸上定位:left、right為橫軸,top、bottom為縱軸,只要包含某個(gè)軸上的一個(gè)定位屬性就算在該軸上有定位。
- textDirection:決定alignment對(duì)齊的參考系即:textDirection的值為TextDirection.ltr,則alignment的start代表左,end代表右;textDirection的值為TextDirection.rtl,則alignment的start代表右,end代表左。
- fit:此參數(shù)用于決定沒有定位的子widget如何去適應(yīng)Stack的大小。StackFit.loose表示使用子widget的大小,StackFit.expand表示擴(kuò)伸到Stack的大小,passthrough不改變子widget的約束條件。
- overflow:此屬性決定如何顯示超出Stack顯示空間的子widget,值為Overflow.clip時(shí),超出部分會(huì)被剪裁(隱藏),值為Overflow.visible 時(shí)則不會(huì)。
Positioned
const Positioned({
Key key,
this.left,
this.top,
this.right,
this.bottom,
this.width,
this.height,
@required Widget child,
})
left、top 、right、 bottom分別代表離Stack左、上、右、底四邊的距離。width和height用于指定定位元素的寬度和高度,注意,此處的width、height 和其它地方的意義稍微有點(diǎn)區(qū)別,此處用于配合left、top 、right、 bottom來定位widget,舉個(gè)例子,在水平方向時(shí),你只能指定left、right、width三個(gè)屬性中的兩個(gè),如指定left和width后,right會(huì)自動(dòng)算出(left+width),如果同時(shí)指定三個(gè)屬性則會(huì)報(bào)錯(cuò),垂直方向同理。
4.IndexedStack
IndexedStack繼承自Stack,它的作用是顯示第index個(gè)child,其他child都是不可見的。所以IndexedStack的尺寸永遠(yuǎn)是跟最大的子節(jié)點(diǎn)尺寸一致。
5.Wrap
子Widget超出屏幕范圍會(huì)自動(dòng)換行,Wrap的很多屬性在Row(包括Flex和Column)中也有,如direction、crossAxisAlignment、textDirection、verticalDirection等
- direction:主軸(mainAxis)的方向,默認(rèn)為水平。
- alignment:主軸方向上的對(duì)齊方式,默認(rèn)為start。
- spacing:主軸方向子widget的間距
- runSpacing:縱軸方向的間距
- runAlignment:縱軸方向的對(duì)齊方式
6.Flow
一個(gè)實(shí)現(xiàn)流式布局算法的widget,使用比較復(fù)雜,一般多實(shí)用Wrap
7.Table
為其子widget使用表格布局算法的widget,
Table({
Key key,
this.children = const <TableRow>[],
this.columnWidths,
this.defaultColumnWidth = const FlexColumnWidth(1.0),
this.textDirection,
this.border,
this.defaultVerticalAlignment = TableCellVerticalAlignment.top,
this.textBaseline,
})
- columnWidths:設(shè)置每一列的寬度。
- defaultColumnWidth:默認(rèn)的每一列寬度值,默認(rèn)情況下均分。
- textDirection:文字方向
- border:表格邊框。
- defaultVerticalAlignment:每一個(gè)cell的垂直方向的alignment。
總共包含5種:
top:被放置在的頂部;
middle:垂直居中;
bottom:放置在底部;
baseline:文本baseline對(duì)齊;
fill:充滿整個(gè)cell。 - textBaseline:defaultVerticalAlignment為baseline的時(shí)候,會(huì)用到這個(gè)屬性。
8.ListView
ListView是最常用的可滾動(dòng)widget,它可以沿一個(gè)方向線性排布所有子widget。
- itemExtent:該參數(shù)如果不為null,則會(huì)強(qiáng)制children的"長(zhǎng)度"為itemExtent的值;這里的"長(zhǎng)度"是指滾動(dòng)方向上子widget的長(zhǎng)度,即如果滾動(dòng)方向是垂直方向,則itemExtent代表子widget的高度,如果滾動(dòng)方向?yàn)樗椒较颍瑒titemExtent代表子widget的長(zhǎng)度。在ListView中,指定itemExtent比讓子widget自己決定自身長(zhǎng)度會(huì)更高效,這是因?yàn)橹付╥temExtent后,滾動(dòng)系統(tǒng)可以提前知道列表的長(zhǎng)度,而不是總是動(dòng)態(tài)去計(jì)算,尤其是在滾動(dòng)位置頻繁變化時(shí)(滾動(dòng)系統(tǒng)需要頻繁去計(jì)算列表高度)。
- shrinkWrap:該屬性表示是否根據(jù)子widget的總長(zhǎng)度來設(shè)置ListView的長(zhǎng)度,默認(rèn)值為false 。默認(rèn)情況下,ListView的會(huì)在滾動(dòng)方向盡可能多的占用空間。當(dāng)ListView在一個(gè)無邊界(滾動(dòng)方向上)的容器中時(shí),shrinkWrap必須為true。
- addAutomaticKeepAlives:該屬性表示是否將列表項(xiàng)(子widget)包裹在AutomaticKeepAlive widget中;典型地,在一個(gè)懶加載列表中,如果將列表項(xiàng)包裹在AutomaticKeepAlive中,在該列表項(xiàng)滑出視口時(shí)該列表項(xiàng)不會(huì)被GC,它會(huì)使用KeepAliveNotification來保存其狀態(tài)。如果列表項(xiàng)自己維護(hù)其KeepAlive狀態(tài),那么此參數(shù)必須置為false。
- addRepaintBoundaries:該屬性表示是否將列表項(xiàng)(子widget)包裹在RepaintBoundary中。當(dāng)可滾動(dòng)widget滾動(dòng)時(shí),將列表項(xiàng)包裹在RepaintBoundary中可以避免列表項(xiàng)重繪,但是當(dāng)列表項(xiàng)重繪的開銷非常小(如一個(gè)顏色塊,或者一個(gè)較短的文本)時(shí),不添加RepaintBoundary反而會(huì)更高效。和addAutomaticKeepAlive一樣,如果列表項(xiàng)自己維護(hù)其KeepAlive狀態(tài),那么此參數(shù)必須置為false。
默認(rèn)構(gòu)造函數(shù)
ListView(
shrinkWrap: true,
padding: EdgeInsets.all(20.0),
children: <Widget>[
Text('I\'m dedicating every day to you'),
Text('Domestic life was never quite my style'),
Text('When you smile, you knock me out, I fall apart'),
Text('And I thought I was so smart'),
],
)
ListView.builder
ListView.builder(
itemCount: 1000,
itemBuilder: (context, index) {
return ListTile(
title: Text("$index"),
);
},
)
ListView.separated
class ListView3 extends StatelessWidget {
@override
Widget build(BuildContext context) {
//下劃線widget預(yù)定義以供復(fù)用。
Widget divider1=Divider(color: Colors.blue,);
Widget divider2=Divider(color: Colors.green);
return ListView.separated(
itemCount: 100,
//列表項(xiàng)構(gòu)造器
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text("$index"));
},
//分割器構(gòu)造器
separatorBuilder: (BuildContext context, int index) {
return index%2==0?divider1:divider2;
},
);
}
}
9.GridView
一個(gè)滾動(dòng)的多列列表
默認(rèn)構(gòu)造函數(shù)
GridView({
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller,
bool primary,
ScrollPhysics physics,
bool shrinkWrap = false,
EdgeInsetsGeometry padding,
@required SliverGridDelegate gridDelegate, //控制子widget layout的委托
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
double cacheExtent,
List<Widget> children = const <Widget>[],
})
- scrollDirection:滾動(dòng)的方向,有垂直和水平兩種,默認(rèn)為垂直方向(Axis.vertical)。
- reverse:默認(rèn)是從上或者左向下或者右滾動(dòng)的,這個(gè)屬性控制是否反向,默認(rèn)值為false,不反向滾動(dòng)。
- controller:控制child滾動(dòng)時(shí)候的位置。
- primary:是否是與父節(jié)點(diǎn)的PrimaryScrollController所關(guān)聯(lián)的主滾動(dòng)視圖。
- physics:滾動(dòng)的視圖如何響應(yīng)用戶的輸入。
- shrinkWrap:滾動(dòng)方向的滾動(dòng)視圖內(nèi)容是否應(yīng)該由正在查看的內(nèi)容所決定。
- padding:四周的空白區(qū)域。
- cacheExtent:緩存區(qū)域。
- gridDelegate:控制GridView中子節(jié)點(diǎn)布局的delegate。
gridDelegate參數(shù),類型是SliverGridDelegate,它的作用是控制GridView子widget如何排列(layout),SliverGridDelegate是一個(gè)抽象類,定義了GridView Layout相關(guān)接口,子類需要通過實(shí)現(xiàn)它們來實(shí)現(xiàn)具體的布局算法,F(xiàn)lutter中提供了兩個(gè)SliverGridDelegate的子類SliverGridDelegateWithFixedCrossAxisCount和SliverGridDelegateWithMaxCrossAxisExtent
SliverGridDelegateWithFixedCrossAxisCount
該類通過確定橫軸子widget的數(shù)量和寬高比從而確定了子widget的最大限時(shí)空間
SliverGridDelegateWithFixedCrossAxisCount({
@required double crossAxisCount,
double mainAxisSpacing = 0.0,
double crossAxisSpacing = 0.0,
double childAspectRatio = 1.0,
})
- crossAxisCount:橫軸子元素的數(shù)量。此屬性值確定后子元素在橫軸的長(zhǎng)度就確定了,即ViewPort橫軸長(zhǎng)度/crossAxisCount。
- mainAxisSpacing:主軸方向的間距。
- crossAxisSpacing:橫軸方向子元素的間距。
- childAspectRatio:子元素在橫軸長(zhǎng)度和主軸長(zhǎng)度的比例。由于crossAxisCount指定后子元素橫軸長(zhǎng)度就確定了,然后通過此參數(shù)值就可以確定子元素在主軸的長(zhǎng)度。
SliverGridDelegateWithMaxCrossAxisExtent
該類通過確定子widget在交叉軸的最大長(zhǎng)度和寬高比從而確定了子widget的最大限時(shí)空間
SliverGridDelegateWithMaxCrossAxisExtent({
double maxCrossAxisExtent,
double mainAxisSpacing = 0.0,
double crossAxisSpacing = 0.0,
double childAspectRatio = 1.0,
})
- maxCrossAxisExtent:子widget在交叉軸的最大長(zhǎng)度,因?yàn)槊總€(gè)子元素的長(zhǎng)度仍然是等分的,所以會(huì)按照設(shè)置的長(zhǎng)度計(jì)算出能展示的數(shù)量然后算出長(zhǎng)度的最大值,當(dāng)maxCrossAxisExtent的值在區(qū)間(450/4,450/3]內(nèi)的話,子元素最終實(shí)際長(zhǎng)度都為150
GridView.count
GridView.count構(gòu)造函數(shù)內(nèi)部使用了SliverGridDelegateWithFixedCrossAxisCount,我們通過它可以快速的創(chuàng)建橫軸固定數(shù)量子元素的GridView
GridView.count(
crossAxisCount: 3,
childAspectRatio: 1.0,
children: <Widget>[
Icon(Icons.ac_unit),
Icon(Icons.airport_shuttle),
Icon(Icons.all_inclusive),
Icon(Icons.beach_access),
Icon(Icons.cake),
Icon(Icons.free_breakfast),
],
);
GridView.extent
GridView.extent構(gòu)造函數(shù)內(nèi)部使用了SliverGridDelegateWithMaxCrossAxisExtent,我們通過它可以快速的創(chuàng)建縱軸子元素為固定最大長(zhǎng)度的的GridView
GridView.extent(
maxCrossAxisExtent: 120.0,
childAspectRatio: 2.0,
children: <Widget>[
Icon(Icons.ac_unit),
Icon(Icons.airport_shuttle),
Icon(Icons.all_inclusive),
Icon(Icons.beach_access),
Icon(Icons.cake),
Icon(Icons.free_breakfast),
],
);
GridView.builder
上面我們介紹的GridView都需要一個(gè)Widget數(shù)組作為其子元素,這些方式都會(huì)提前將所有子widget都構(gòu)建好,所以只適用于子Widget數(shù)量比較少時(shí),當(dāng)子widget比較多時(shí),我們可以通過GridView.builder來動(dòng)態(tài)創(chuàng)建子Widget。
GridView.builder 必須指定的參數(shù)有兩個(gè):
GridView.builder(
...
@required SliverGridDelegate gridDelegate,
@required IndexedWidgetBuilder itemBuilder,
)