今天,我們來聊聊網(wǎng)格布局GridView。
構(gòu)造數(shù)據(jù)(生成Widgets)
List<String> getDataList() {
List<String> list = [];
for (int i = 0; i < 100; i++) {
list.add(i.toString());
}
return list;
}
List<Widget> getWidgetList() {
return getDataList().map((item) => getItemContainer(item)).toList();
}
Widget getItemContainer(String item) {
return Container(
alignment: Alignment.center,
child: Text(
item,
style: TextStyle(color: Colors.white, fontSize: 20),
),
color: Colors.blue,
);
}
GridView有好幾種寫法露乏,萬變不離其宗车海。我們一個(gè)個(gè)來看看笛园。
寫法一:GridView.count
GridView.count(
//水平子Widget之間間距
crossAxisSpacing: 10.0,
//垂直子Widget之間間距
mainAxisSpacing: 30.0,
//GridView內(nèi)邊距
padding: EdgeInsets.all(10.0),
//一行的Widget數(shù)量
crossAxisCount: 2,
//子Widget寬高比例
childAspectRatio: 2.0,
//子Widget列表
children: getWidgetList(),
);
效果:
對(duì)于這種寫法,此時(shí)單個(gè)Widget的寬高已經(jīng)不起作用了。
在我上面構(gòu)造數(shù)據(jù)的那一步中研铆,我并沒有指定Container
的的寬高埋同,這里我們就將其寬高設(shè)置為5,看下效果棵红。
Widget getItemContainer(String item) {
return Container(
width: 5.0,
height: 5.0,
alignment: Alignment.center,
child: Text(
item,
style: TextStyle(color: Colors.white, fontSize: 20),
),
color: Colors.blue,
);
}
可以看出沒有效果凶赁。因?yàn)椋覀冊(cè)谶@里已經(jīng)指定了每一行分成幾列以及寬高比逆甜,還有邊距等等哟冬。所以,我們后面再指定單個(gè)item的寬高忆绰,已經(jīng)無效浩峡。
其實(shí)GridView跟我之前講過的ListView,基本類似错敢,都是BoxScrollView
的子類翰灾。
寫法二:GridView.builder
@override
Widget build(BuildContext context) {
List<String> datas = getDataList();
return GridView.builder(
itemCount: datas.length,
//SliverGridDelegateWithFixedCrossAxisCount 構(gòu)建一個(gè)橫軸固定數(shù)量Widget
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
//橫軸元素個(gè)數(shù)
crossAxisCount: 3,
//縱軸間距
mainAxisSpacing: 20.0,
//橫軸間距
crossAxisSpacing: 10.0,
//子組件寬高長度比例
childAspectRatio: 1.0),
itemBuilder: (BuildContext context, int index) {
//Widget Function(BuildContext context, int index)
return getItemContainer(datas[index]);
});
}
abstract class SliverGridDelegate gridDelegate
用來指定GridView
的構(gòu)建方式,具體實(shí)現(xiàn)有兩個(gè)稚茅。
剛才這里例子纸淮,使用的
SliverGridDelegateWithFixedCrossAxisCount
。下面亚享,我們來使用它的另一個(gè)實(shí)現(xiàn)SliverGridDelegateWithMaxCrossAxisExtent
咽块。
寫法三:GridView.builder(SliverGridDelegateWithMaxCrossAxisExtent)
GridView.builder(
itemCount: datas.length,
itemBuilder: (BuildContext context, int index) {
return getItemContainer(datas[index]);
},
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
//單個(gè)子Widget的水平最大寬度
maxCrossAxisExtent: 200,
//水平單個(gè)子Widget之間間距
mainAxisSpacing: 20.0,
//垂直單個(gè)子Widget之間間距
crossAxisSpacing: 10.0
),
);
對(duì)于SliverGridDelegateWithMaxCrossAxisExtent
而言,水平方向元素個(gè)數(shù)不再固定欺税,其水平個(gè)數(shù)也就是有幾列侈沪,由maxCrossAxisExtent
和屏幕的寬度以及padding
和mainAxisSpacing
等決定。
例如:我這里的虛擬機(jī)寬度為400晚凿,當(dāng)maxCrossAxisExtent:50
時(shí)亭罪,有8列;當(dāng)maxCrossAxisExtent:100
時(shí)歼秽,有4列应役。如下:
maxCrossAxisExtent | 效果 |
---|---|
內(nèi)容 | 內(nèi)容 |
maxCrossAxisExtent:50 | image.png
|
maxCrossAxisExtent:100 | image.png
|
寫法四:
@override
Widget build(BuildContext context) {
List<String> datas = getDataList();
return GridView.custom(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, mainAxisSpacing: 10.0, crossAxisSpacing: 20.0, ),
childrenDelegate: SliverChildBuilderDelegate((context, position) {
return getItemContainer(datas[position]);
}, childCount: datas.length));
}
這幾個(gè)參數(shù),上面都講過了燥筷,不再贅述了箩祥。
本文代碼地址
Flutter 豆瓣客戶端,誠心開源
Flutter Container
Flutter SafeArea
Flutter Row Column MainAxisAlignment Expanded
Flutter Image全解析
Flutter 常用按鈕總結(jié)
Flutter ListView豆瓣電影排行榜
Flutter Card
Flutter Navigator&Router(導(dǎo)航與路由)
OverscrollNotification不起效果引起的Flutter感悟分享
Flutter 上拉抽屜實(shí)現(xiàn)
Flutter 豆瓣客戶端肆氓,誠心開源
Flutter 更改狀態(tài)欄顏色