Flutter網(wǎng)格型布局 - GridView篇

1. 前言

Flutter作為時下最流行的技術(shù)之一悦陋,憑借其出色的性能以及抹平多端的差異優(yōu)勢,早已引起大批技術(shù)愛好者的關(guān)注认烁,甚至一些閑魚美團(tuán)介汹,騰訊等大公司均已投入生產(chǎn)使用却嗡。雖然目前其生態(tài)還沒有完全成熟,但身靠背后的Google加持嘹承,其發(fā)展速度已經(jīng)足夠驚人窗价,可以預(yù)見將來對Flutter開發(fā)人員的需求也會隨之增長。

無論是為了現(xiàn)在的技術(shù)嘗鮮還是將來的潮流趨勢叹卷,都9102年了撼港,作為一個前端開發(fā)者,似乎沒有理由不去嘗試它骤竹。正是帶著這樣的心理帝牡,筆者也開始學(xué)習(xí)Flutter,同時建了一個用于練習(xí)的倉庫蒙揣,后續(xù)所有代碼都會托管在上面靶溜,歡迎star,一起學(xué)習(xí)懒震。這是我寫的Flutter系列文章:

經(jīng)過上一篇ListView組件的學(xué)習(xí)罩息,我們已經(jīng)對滾動型組件的使用有了初步認(rèn)識,這對今天要學(xué)習(xí)的GridView組件十分有幫助个扰。因為兩者都繼承自BoxScrollView扣汪,所以兩者的屬性有80%以上是相同的,用法非常相似锨匆。

而且如下圖所示可見崭别,GridView網(wǎng)格布局在app中的使用頻率其實非常高冬筒,所以接下來就讓我們來看看在Flutter中如何使用吧~

app中網(wǎng)格布局的使用

2. 初識GridView

今天我們的主角GridView一共有5個構(gòu)造函數(shù):GridViewGridView.builder茅主,GridView.count舞痰,GridView.extentGridView.custom。但是不用慌诀姚,因為可以說其實掌握其默認(rèn)構(gòu)造函數(shù)就都會了~

來看下GridView構(gòu)造函數(shù)(已省略不常用屬性):

GridView({
  Key key,
  Axis scrollDirection = Axis.vertical,
  bool reverse = false,
  ScrollController controller,
  ScrollPhysics physics,
  bool shrinkWrap = false,
  EdgeInsetsGeometry padding,
  @required this.gridDelegate,
  double cacheExtent,
  List<Widget> children = const <Widget>[],
})

雖然又是一大堆屬性响牛,但是大部分都很熟悉,老朋友嘛~除了一個必填參數(shù)gridDelegate外赫段,全和ListView默認(rèn)構(gòu)造函數(shù)的參數(shù)一樣呀打,這也是文章開頭為什么說掌握了ListView再學(xué)GridView非常容易的原因。

那么接下來糯笙,就讓我們來重點關(guān)注下gridDelegate這個參數(shù)贬丛,它其實是GridView組件如何控制排列子元素的一個委托。跟蹤源碼我們可以在scroll_view.dart中看到给涕,gridDelegate的類型是SliverGridDelegate豺憔,進(jìn)一步跟蹤進(jìn)sliver_grid.dart可以看到SliverGridDelegate其實是一個抽象類,而且一共有兩個實現(xiàn)類:

  • SliverGridDelegateWithFixedCrossAxisCount:用于固定列數(shù)的場景够庙;
  • SliverGridDelegateWithMaxCrossAxisExtent:用于子元素有最大寬度限制的場景恭应;

2.1 SliverGridDelegateWithFixedCrossAxisCount

我們先來看下SliverGridDelegateWithFixedCrossAxisCount,根據(jù)類名我們也能大概猜它是干什么用的:如果你的布局中每一行的列數(shù)是固定的耘眨,那你就應(yīng)該用它昼榛。

來看下其構(gòu)造函數(shù):

SliverGridDelegateWithFixedCrossAxisCount({
  @required this.crossAxisCount,
  this.mainAxisSpacing = 0.0,
  this.crossAxisSpacing = 0.0,
  this.childAspectRatio = 1.0,
})
  • crossAxisCount:列數(shù),即一行有幾個子元素剔难;
  • mainAxisSpacing:主軸方向上的空隙間距褒纲;
  • crossAxisSpacing:次軸方向上的空隙間距;
  • childAspectRatio:子元素的寬高比例钥飞。
屬性解釋

想必看到上面的示例圖莺掠,你就秒懂其中各個參數(shù)的含義了。不過读宙,這里有一點需要特別注意:如果你的子元素寬高比例不為1彻秆,那么你一定要設(shè)置childAspectRatio屬性

2.2 SliverGridDelegateWithMaxCrossAxisExtent

SliverGridDelegateWithMaxCrossAxisExtent在實際應(yīng)用中可能會比較少结闸,來看下其構(gòu)造函數(shù):

SliverGridDelegateWithMaxCrossAxisExtent({
  @required this.maxCrossAxisExtent,
  this.mainAxisSpacing = 0.0,
  this.crossAxisSpacing = 0.0,
  this.childAspectRatio = 1.0,
})

可以看到除了maxCrossAxisExtent外唇兑,其他參數(shù)和SliverGridDelegateWithFixedCrossAxisCount都是一樣的。那么maxCrossAxisExtent是干什么的呢桦锄?我們來看個例子:

假如手機屏寬375扎附,crossAxisSpacing值為0

  • maxCrossAxisExtent值為125時结耀,網(wǎng)格列數(shù)將是3留夜。因為125 * 3 = 375匙铡,剛好,每一列的寬度就是375/3碍粥。
  • maxCrossAxisExtent值為126時鳖眼,網(wǎng)格列數(shù)將是3。因為126 * 3 > 375嚼摩,顯示不下钦讳,每一列的寬度將是375/3
  • maxCrossAxisExtent值為124時枕面,網(wǎng)格列數(shù)將是4愿卒。因為124 * 3 < 375,仍有多余潮秘,每一列的寬度將是375/4琼开。

可以看到,maxCrossAxisExtent其實就是告訴GridView組件子元素的最大寬度可能是多少唇跨,然后計算得到合適的列寬(實際上,我們也很少這么應(yīng)用衬衬,所以這種方法的使用頻率不高)买猖。

3. 實際應(yīng)用

經(jīng)過前面的介紹,我們已經(jīng)對GrdiView組件有了初步了解滋尉,下面就來看看如何使用玉控。還記得之前GridView的各種構(gòu)造函數(shù)嗎?其實:

  1. GridView默認(rèn)構(gòu)造函數(shù)可以類比于ListView默認(rèn)構(gòu)造函數(shù)狮惜,適用于有限個數(shù)子元素的場景高诺,因為GridView組件會一次性全部渲染children中的子元素組件;
  2. GridView.builder構(gòu)造函數(shù)可以類比于ListView.builder構(gòu)造函數(shù)碾篡,適用于長列表的場景虱而,因為GridView組件會根據(jù)子元素是否出現(xiàn)在屏幕內(nèi)而動態(tài)創(chuàng)建銷毀,減少內(nèi)存消耗开泽,更高效渲染牡拇;
  3. GridView.count構(gòu)造函數(shù)是GrdiView使用SliverGridDelegateWithFixedCrossAxisCount的簡寫(語法糖),效果完全一致穆律;
  4. GridView.extent構(gòu)造函數(shù)式GridView使用SliverGridDelegateWithMaxCrossAxisExtent的簡寫(語法糖)惠呼,效果完全一致。

先來看一個簡單的例子峦耘,它使用到GridView.count構(gòu)造函數(shù)模仿美團(tuán)外賣首頁服務(wù)列表(服務(wù)菜單項的代碼可以看這里剔蹋,也算是對基礎(chǔ)組件使用的進(jìn)一步鞏固):

代碼(文件地址

GridView.count(
  crossAxisCount: 5,
  padding: EdgeInsets.symmetric(vertical: 0),
  children: serviceList.map((item) => ServiceItem(data: item)).toList(),
)

/*************/
/* 完全等同于 */
/************/

GridView(
  padding: EdgeInsets.symmetric(vertical: 0),
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 5,
  ),
  children: serviceList.map((item) => ServiceItem(data: item)).toList(),
)

預(yù)覽

美團(tuán)外賣首頁服務(wù)列表

再來看一個模仿喜馬拉雅中相聲列表用到GridView.builder創(chuàng)建網(wǎng)格布局的具體例子(相聲卡片的代碼可以看這里):

代碼(文件地址

GridView.builder(
  shrinkWrap: true,
  itemCount: programmeList.length,
  physics: NeverScrollableScrollPhysics(),
  padding: EdgeInsets.symmetric(horizontal: 16),
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 3,
    mainAxisSpacing: 10,
    crossAxisSpacing: 10,
    childAspectRatio: 0.7,
  ),
  itemBuilder: (context, index) {
    return Programme(data: programmeList[index]);
  },
)

預(yù)覽

喜馬拉雅 - 相聲列表

4. 總結(jié)

本文先是介紹了GridView組件的屬性含義,并著重講解了SliverGridDelegateWithFixedCrossAxisCountSliverGridDelegateWithMaxCrossAxisExtent分別適用的應(yīng)用場景辅髓。然后泣崩,通過兩個實際的應(yīng)用例子介紹了GridView組件常用的構(gòu)造函數(shù)使用方法少梁。希望通過本文的介紹,你可以掌握Flutter中網(wǎng)格型布局的使用~

本文所有代碼托管在這兒律想,也可以關(guān)注我的Blog猎莲,歡迎一起交流學(xué)習(xí)~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市技即,隨后出現(xiàn)的幾起案子著洼,更是在濱河造成了極大的恐慌,老刑警劉巖而叼,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件身笤,死亡現(xiàn)場離奇詭異,居然都是意外死亡葵陵,警方通過查閱死者的電腦和手機液荸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來脱篙,“玉大人娇钱,你說我怎么就攤上這事“砝В” “怎么了文搂?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長秤朗。 經(jīng)常有香客問我煤蹭,道長,這世上最難降的妖魔是什么取视? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任硝皂,我火速辦了婚禮,結(jié)果婚禮上作谭,老公的妹妹穿的比我還像新娘稽物。我一直安慰自己,他們只是感情好折欠,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布姨裸。 她就那樣靜靜地躺著,像睡著了一般怨酝。 火紅的嫁衣襯著肌膚如雪傀缩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天农猬,我揣著相機與錄音赡艰,去河邊找鬼。 笑死斤葱,一個胖子當(dāng)著我的面吹牛慷垮,可吹牛的內(nèi)容都是我干的揖闸。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼料身,長吁一口氣:“原來是場噩夢啊……” “哼汤纸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起芹血,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤贮泞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后幔烛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啃擦,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年饿悬,在試婚紗的時候發(fā)現(xiàn)自己被綠了令蛉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡狡恬,死狀恐怖珠叔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情弟劲,我是刑警寧澤祷安,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站函卒,受9級特大地震影響辆憔,放射性物質(zhì)發(fā)生泄漏撇眯。R本人自食惡果不足惜报嵌,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望熊榛。 院中可真熱鬧锚国,春花似錦、人聲如沸玄坦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽煎楣。三九已至豺总,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間择懂,已是汗流浹背喻喳。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留困曙,地道東北人表伦。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓谦去,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蹦哼。 傳聞我的和親對象是個殘疾皇子鳄哭,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 本文對Flutter的29種布局控件進(jìn)行了總結(jié)分類,講解一些布局上的優(yōu)化策略纲熏,以及面對具體的布局時妆丘,如何去選擇控件...
    Q吹個大氣球Q閱讀 10,537評論 15 153
  • 1. 前言 Flutter作為時下最流行的技術(shù)之一,憑借其出色的性能以及抹平多端的差異優(yōu)勢赤套,早已引起大批技術(shù)愛好者...
    小石頭若海閱讀 14,731評論 3 27
  • 國慶后面兩天在家學(xué)習(xí)整理了一波flutter飘痛,基本把能擼過能看到的代碼都過了一遍,此文篇幅較長容握,建議保存(star...
    Nealyang閱讀 4,338評論 1 17
  • 本文對Flutter的29種布局控件進(jìn)行了總結(jié)分類宣脉,講解一些布局上的優(yōu)化策略,以及面對具體的布局時剔氏,如何去選擇控件...
    chilim閱讀 1,299評論 0 19
  • 回想中找到回家的路 我還在尋求答案塑猖,我回想起自己的身世:我是個孤兒,我雖然有父母谈跛、有家人羊苟、有家,但我知道感憾,他們不是...
    本體悅閱讀 273評論 0 1