本文目錄
-
- 前言
- GridView
- CustomScrollView
- Flex
- Wrap
上一篇介紹了多元素元件:ListView,Scaffold,AppBar,Row,Column,這一節将接着上一篇博文,介紹GridView,CustomScrollView,Flex,以及Wrap多元素元件(下圖為CustomScrollView實作效果)

首先,就是GridView,它和ListView相似,隻不過表現形式為網格形式,可以把它看成Android的LayoutManager。如果GridView元件掌握的很好,那麼App界面也是會非常好看,給人賞心悅目。不過需要注意的是,GridView中的gridDelegate屬性,其類型是SliverGridDelegate,是一個抽象類,通過該類可以控制GridView的排列顯示方式,我們先來看看官方文檔的使用方式:
body: GridView.count(
primary: false,
padding: const EdgeInsets.all(20.0),
crossAxisSpacing: 10.0,
crossAxisCount: 2,
children: <Widget>[
const Text("11111111111111111111"),
const Text("22222222222222222222"),
const Text("33333333333333333333"),
const Text("44444444444444444444"),
const Text("55555555555555555555"),
const Text("66666666666666666666"),
],
),
這裡我們沒有看到代碼中使用SliverGridDelegate,那麼它在哪裡呢?其實,在GridView.count中的構造函數裡已經傳入了預設的gridDelegate,通過開發工具我們進入它的源碼:
gridDelegate = SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: crossAxisCount,
mainAxisSpacing: mainAxisSpacing,
crossAxisSpacing: crossAxisSpacing,
childAspectRatio: childAspectRatio,
),
源碼裡已經使用了SliverGridDelegateWithFixedCrossAxisCount。它有四個屬性,我們先來看看他們的定義:
屬性 | 取值 |
---|---|
crossAxisCount | 橫向軸子元素的數量 |
mainAxisSpacing | 橫向軸之間的間距 |
crossAxisSpacing | 子元素之間的間距 |
childAspectRatio | 子元素的寬高比,比如2.0就表示寬度是高度的2倍 |
gridDelegate還支援SliverGridDelegateWithMaxCrossAxisExtent,同時GridView也和ListView一樣支援GridView.builder來建立,使用代碼與ListView差不多,這裡就不在贅述了,上面代碼實作效果如下:
在實際應用裡,布局情況并不是非此即彼,一般一個界面不會隻有一個滾動清單元件,很可能還有别的元件,這個時候CustomScrollView就有用處了,它的使用代碼如下:
return CustomScrollView(
slivers: <Widget>[
const SliverAppBar(
pinned: true,//标題欄是否固定
expandedHeight: 250.0,//合并的高度,預設是狀态欄的高度加AppBar的高度
flexibleSpace: FlexibleSpaceBar(
title: Text("我的标題"),
),
),
SliverGrid(
delegate: SliverChildBuilderDelegate((BuildContext context,int index){
return Container(
alignment: Alignment.center,
color: Colors.teal[100*(index%9)],
child: Text("第$index個"),
);
},childCount: 20),
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,//單個子Widget的水準最大寬度
mainAxisSpacing: 10.0,//水準單個子Widget之間間距
crossAxisSpacing: 10.0,//垂直單個子Widget之間間距
childAspectRatio: 4.0,//寬高比
)
),
SliverFixedExtentList(
itemExtent: 50.0,
delegate: SliverChildBuilderDelegate((BuildContext context,int index){
return Container(
alignment: Alignment.center,
color: Colors.lightBlue[100*(index%9)],
child: Text("第$index個"),
);
}),
),
],
);
這段代碼看起來非常複雜其實很好了解,在Scaffold中,Appbar等價于SliverAppBar,剛講解的GridView等價于SliverGrid,而ListView等價于SliverFixedExtentList,是以這是一個包含了二個滑動元件的一個布局容器,其他的代碼中有注釋,這裡就不贅述了。(顯示效果如博文首圖)
特别注意:轉換後的元件都是以“Sliver”開頭的,其本身是不具備滾動特性的,但是放在CustomScrollView中之後,則可以實作滾動的功能。
Flex英文意思是屈伸,活動,在Flutter裡面也就是彈性布局,該布局借鑒了前端裡的Flex布局方式。用法也十分簡單,我們可以在Flex中傳入一些參數,其具體屬性如下表:
direction | Axis.vertical表示垂直方向,Axis.horizontal表示水準方向 |
flex | 彈性系數,大于0會按比例來分割,等于0不會擴充占用的空間 |
可以把它了解為android:layout_weight屬性,使用代碼如下:
return Scaffold(
appBar: AppBar(title: Text("Flex布局玩法"),),
body: Column(
children: <Widget>[
Container(
height: 400.0,
child: Flex(
direction: Axis.vertical,
children: <Widget>[
Expanded(
flex: 1,
child: Container(
color: Colors.red,
),
),
Expanded(
flex: 2,
child: Container(
color: Colors.yellow,
),
),
],
),
),
Container(
height: 120.0,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
flex: 2,
child: Container(
color: Colors.blueAccent,
),
),
Expanded(
flex: 1,
child: Container(
color: Colors.red,
),
),
],
),
),
],
),
);
return Scaffold(
appBar: AppBar(title: Text("Wrap元件玩法"),),
body: Wrap(
spacing: 4.0,
runSpacing: 4.0,
children: <Widget>[
Container(
color: Colors.yellow,
child: Text("Python程式設計指南",style: new TextStyle(color: Colors.lightBlue),),
),
Container(
color: Colors.yellow,
child: Text("Android程式設計指南",style: new TextStyle(color: Colors.lightBlue),)
),
Container(
color: Colors.yellow,
child: Text("Flutter",style: new TextStyle(color: Colors.lightBlue),)
),
Container(
color: Colors.yellow,
child: Text("VUE",style: new TextStyle(color: Colors.lightBlue),)
),
Container(
color: Colors.yellow,
child: Text("Scaffold",style: new TextStyle(color: Colors.lightBlue),)
),
Container(
color: Colors.yellow,
child: Text("Container",style: new TextStyle(color: Colors.lightBlue),)
),
Container(
color: Colors.yellow,
child: Text("Colors",style: new TextStyle(color: Colors.lightBlue),)
),
Container(
color: Colors.yellow,
child: Text("Colors.yellow",style: new TextStyle(color: Colors.lightBlue),)
),
],
),
);