Flutter Widget(3):多節(jié)點(diǎn)Widget

1.Row

線性布局,將children排成一行,主軸為水平方向署鸡,交叉軸為垂直方向如失。

  • textDirection:表示水平方向子widget的布局順序是從左往右還是從右往左绊诲。
  • mainAxisSize:主軸方向的占用空間。默認(rèn)是MainAxisSize.max褪贵,表示盡可能多的占用水平方向的空間掂之,此時(shí)無論子widgets實(shí)際占用多少水平空間,Row的寬度始終等于水平方向的最大寬度脆丁;而MainAxisSize.min表示盡可能少的占用水平空間世舰,當(dāng)子widgets沒有占滿水平剩余空間,則Row的實(shí)際寬度等于所有子widgets占用的的水平空間槽卫;
  • mainAxisAlignment:主軸對齊方式跟压,如果mainAxisSize值為MainAxisSize.min ,則此屬性無意義歼培,因?yàn)樽觲idgets的寬度等于Row的寬度震蒋。只有當(dāng)mainAxisSize的值為MainAxisSize.max時(shí),此屬性才有意義躲庄。textDirection是mainAxisAlignment的參考系查剖,textDirection取值為TextDirection.ltr時(shí),則MainAxisAlignment.start表示左對齊读跷,textDirection取值為TextDirection.rtl時(shí)表示從右對齊梗搅。
  • crossAxisAlignment:交叉軸對齊方式,Row的高度等于子Widgets中最高的子元素高度效览。crossAxisAlignment的參考系是verticalDirection无切,即verticalDirection值為VerticalDirection.down時(shí)crossAxisAlignment.start指頂部對齊,verticalDirection值為VerticalDirection.up時(shí)丐枉,crossAxisAlignment.start指底部對齊哆键;而crossAxisAlignment.end和crossAxisAlignment.start正好相反;
  • children :子widget數(shù)組

2.Column

Column可以在垂直方向排列其子widget瘦锹。參數(shù)和Row一樣籍嘹,不同的是布局方向?yàn)榇怪保鬏S縱軸正好相反

如果Row里面嵌套Row弯院,或者Column里面再嵌套Column辱士,那么只有對最外面的Row或Column會占用盡可能大的空間,里面Row或Column所占用的空間為實(shí)際大小

3.Stack

可以允許其子widget簡單的堆疊在一起,相當(dāng)于Android中的FrameLayout听绳,

  • alignment:此參數(shù)決定如何去對齊沒有定位(沒有使用Positioned)或部分定位的子widget颂碘。所謂部分定位,在這里特指沒有在某一個(gè)軸上定位:left椅挣、right為橫軸头岔,top塔拳、bottom為縱軸,只要包含某個(gè)軸上的一個(gè)定位屬性就算在該軸上有定位峡竣。
  • textDirection:決定alignment對齊的參考系即: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í),超出部分會被剪裁(隱藏)受楼,值為Overflow.visible 時(shí)則不會垦搬。

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會自動算出(left+width),如果同時(shí)指定三個(gè)屬性則會報(bào)錯(cuò),垂直方向同理靴寂。

4.IndexedStack

IndexedStack繼承自Stack,它的作用是顯示第index個(gè)child召耘,其他child都是不可見的百炬。所以IndexedStack的尺寸永遠(yuǎn)是跟最大的子節(jié)點(diǎn)尺寸一致。

5.Wrap

子Widget超出屏幕范圍會自動換行污它,Wrap的很多屬性在Row(包括Flex和Column)中也有剖踊,如direction、crossAxisAlignment衫贬、textDirection德澈、verticalDirection等

  • direction:主軸(mainAxis)的方向,默認(rèn)為水平固惯。
  • alignment:主軸方向上的對齊方式梆造,默認(rèn)為start。
  • spacing:主軸方向子widget的間距
  • runSpacing:縱軸方向的間距
  • runAlignment:縱軸方向的對齊方式

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對齊;
    fill:充滿整個(gè)cell香缺。
  • textBaseline:defaultVerticalAlignment為baseline的時(shí)候手销,會用到這個(gè)屬性。

8.ListView

ListView是最常用的可滾動widget图张,它可以沿一個(gè)方向線性排布所有子widget锋拖。

  • itemExtent:該參數(shù)如果不為null,則會強(qiáng)制children的"長度"為itemExtent的值祸轮;這里的"長度"是指滾動方向上子widget的長度兽埃,即如果滾動方向是垂直方向,則itemExtent代表子widget的高度适袜,如果滾動方向?yàn)樗椒较虮恚瑒titemExtent代表子widget的長度。在ListView中,指定itemExtent比讓子widget自己決定自身長度會更高效售貌,這是因?yàn)橹付╥temExtent后给猾,滾動系統(tǒng)可以提前知道列表的長度,而不是總是動態(tài)去計(jì)算颂跨,尤其是在滾動位置頻繁變化時(shí)(滾動系統(tǒng)需要頻繁去計(jì)算列表高度)敢伸。
  • shrinkWrap:該屬性表示是否根據(jù)子widget的總長度來設(shè)置ListView的長度,默認(rèn)值為false 恒削。默認(rèn)情況下池颈,ListView的會在滾動方向盡可能多的占用空間。當(dāng)ListView在一個(gè)無邊界(滾動方向上)的容器中時(shí)钓丰,shrinkWrap必須為true躯砰。
  • addAutomaticKeepAlives:該屬性表示是否將列表項(xiàng)(子widget)包裹在AutomaticKeepAlive widget中;典型地携丁,在一個(gè)懶加載列表中琢歇,如果將列表項(xiàng)包裹在AutomaticKeepAlive中,在該列表項(xiàng)滑出視口時(shí)該列表項(xiàng)不會被GC则北,它會使用KeepAliveNotification來保存其狀態(tài)矿微。如果列表項(xiàng)自己維護(hù)其KeepAlive狀態(tài),那么此參數(shù)必須置為false尚揣。
  • addRepaintBoundaries:該屬性表示是否將列表項(xiàng)(子widget)包裹在RepaintBoundary中涌矢。當(dāng)可滾動widget滾動時(shí),將列表項(xiàng)包裹在RepaintBoundary中可以避免列表項(xiàng)重繪快骗,但是當(dāng)列表項(xiàng)重繪的開銷非常心缺印(如一個(gè)顏色塊,或者一個(gè)較短的文本)時(shí)方篮,不添加RepaintBoundary反而會更高效名秀。和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è)滾動的多列列表

默認(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:滾動的方向巾表,有垂直和水平兩種汁掠,默認(rèn)為垂直方向(Axis.vertical)。
  • reverse:默認(rèn)是從上或者左向下或者右滾動的集币,這個(gè)屬性控制是否反向考阱,默認(rèn)值為false,不反向滾動鞠苟。
  • controller:控制child滾動時(shí)候的位置乞榨。
  • primary:是否是與父節(jié)點(diǎn)的PrimaryScrollController所關(guān)聯(lián)的主滾動視圖秽之。
  • physics:滾動的視圖如何響應(yīng)用戶的輸入。
  • shrinkWrap:滾動方向的滾動視圖內(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ù)量。此屬性值確定后子元素在橫軸的長度就確定了,即ViewPort橫軸長度/crossAxisCount溃槐。
  • mainAxisSpacing:主軸方向的間距匣砖。
  • crossAxisSpacing:橫軸方向子元素的間距。
  • childAspectRatio:子元素在橫軸長度和主軸長度的比例昏滴。由于crossAxisCount指定后子元素橫軸長度就確定了猴鲫,然后通過此參數(shù)值就可以確定子元素在主軸的長度。

SliverGridDelegateWithMaxCrossAxisExtent

該類通過確定子widget在交叉軸的最大長度和寬高比從而確定了子widget的最大限時(shí)空間

SliverGridDelegateWithMaxCrossAxisExtent({
  double maxCrossAxisExtent,
  double mainAxisSpacing = 0.0,
  double crossAxisSpacing = 0.0,
  double childAspectRatio = 1.0,
})
  • maxCrossAxisExtent:子widget在交叉軸的最大長度谣殊,因?yàn)槊總€(gè)子元素的長度仍然是等分的拂共,所以會按照設(shè)置的長度計(jì)算出能展示的數(shù)量然后算出長度的最大值,當(dāng)maxCrossAxisExtent的值在區(qū)間(450/4姻几,450/3]內(nèi)的話宜狐,子元素最終實(shí)際長度都為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)建縱軸子元素為固定最大長度的的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ù)組作為其子元素抚恒,這些方式都會提前將所有子widget都構(gòu)建好,所以只適用于子Widget數(shù)量比較少時(shí)络拌,當(dāng)子widget比較多時(shí)俭驮,我們可以通過GridView.builder來動態(tài)創(chuàng)建子Widget。

GridView.builder 必須指定的參數(shù)有兩個(gè):

GridView.builder(
 ...
 @required SliverGridDelegate gridDelegate, 
 @required IndexedWidgetBuilder itemBuilder,
)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末春贸,一起剝皮案震驚了整個(gè)濱河市混萝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌祥诽,老刑警劉巖譬圣,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異雄坪,居然都是意外死亡厘熟,警方通過查閱死者的電腦和手機(jī)屯蹦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绳姨,“玉大人登澜,你說我怎么就攤上這事∑” “怎么了脑蠕?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長跪削。 經(jīng)常有香客問我谴仙,道長,這世上最難降的妖魔是什么碾盐? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任晃跺,我火速辦了婚禮,結(jié)果婚禮上毫玖,老公的妹妹穿的比我還像新娘掀虎。我一直安慰自己,他們只是感情好付枫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布烹玉。 她就那樣靜靜地躺著,像睡著了一般阐滩。 火紅的嫁衣襯著肌膚如雪二打。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天叶眉,我揣著相機(jī)與錄音址儒,去河邊找鬼。 笑死衅疙,一個(gè)胖子當(dāng)著我的面吹牛莲趣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播饱溢,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼喧伞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了绩郎?” 一聲冷哼從身側(cè)響起潘鲫,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肋杖,沒想到半個(gè)月后溉仑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡状植,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年浊竟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了怨喘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡振定,死狀恐怖必怜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情后频,我是刑警寧澤梳庆,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站卑惜,受9級特大地震影響膏执,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜露久,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一胧后、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧抱环,春花似錦、人聲如沸纸巷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘤旨。三九已至梯啤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間存哲,已是汗流浹背因宇。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留祟偷,地道東北人察滑。 一個(gè)月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像修肠,于是被迫代替她去往敵國和親贺辰。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355