歡迎關注『郝先生 談技術』頭條號,您的關注,是對作者最大的鼓勵,也是作者創作的動力。
在 等系列文章中,我們完成了展示行星信息的卡片Widget。這篇文章中我們將學習使用ListView Widget,以列表的形式展示多條行星信息。加黑字體代表新增代碼。
創建數據源
在上篇文章 中,我們定義了行星的數據結構,接下來我們利用它創建一組數據源。
在HomePageBody.dart中添加如下代碼:
final List
const Planet(
id: 1,
name: "火星",
location: "銀河系",
distance: "220.0m km",
gravity: "3.7 m/s",
description: "遙遠的星球",
image: "assets/img/mars.png",
),
const Planet(
id: 1,
name: "海王星",
location: "銀河系",
distance: "54.6m km",
gravity: "11.15 m/s",
description: "遙遠的星球",
image: "assets/img/neptune.png",
),
const Planet(
id: 1,
name: "月球",
location: "銀河系",
distance: "54.6m km",
gravity: "1.622 m/s",
description: "遙遠的星球",
image: "assets/img/moon.png",
),
const Planet(
id: 1,
name: "地球",
location: "銀河系",
distance: "0m km",
gravity: "9.8 m/s",
description: "我們的星球",
image: "assets/img/earth.png",
),
const Planet(
id: 1,
name: "水星",
location: "銀河系",
distance: "54.6m km",
gravity: "3.7 m/s",
description: "遙遠的星球",
image: "assets/img/mercury.png",
),
];
創建列表
我們使用Flutter提供的ListView Widget根據數據源創建一個列表,類似Android中的Adapter類。ListView.builder()函數參數如下:
- itemCount : 行數
- itemBuilder : 函數,創建每行的Widget
- itemExtent : 設置每行的高度,如果行高固定的話,可以加快渲染速度
在HomePageBody.dart中添加如下代碼:
@override
Widget build(BuildContext context) {
return new ListView.builder(
itemBuilder: (context, index) => new PlanetRow(planets[index]),
itemCount: planets.length,
itemExtent: 152.0,
padding: new EdgeInsets.symmetric(vertical: 16.0),
);
}
運行後報錯,原因是ListView無法計算自身高度。一種解決辦法是將它放到一個高度一定的容器部件內,但是這樣又產生了新的問題,不同的設備高度不同。所以一個更好的解決辦法是使用Expanded Widget。
修改後的代碼如下:
@override
Widget build(BuildContext context) {
return new Expanded(
child: new ListView.builder(
itemBuilder: (context, index) => new PlanetRow(planets[index]),
itemCount: planets.length,
itemExtent: 152.0,
padding: new EdgeInsets.symmetric(vertical: 16.0),
));
}
上面的代碼中我們還設置了每一行的上下向內偏移16.0px。
運行項目
完成後點擊Hot reload,iPhone8模擬器效果如下:
換一種實現方式,初識Slivers Widget
儘管我們已經使用ListView完成了上述頁面,但是我還要給大家介紹一下利用Slivers Widget的實現方式。Slivers是一個非常強大的工具,可滾動部件都是基於Slivers實現的。
一個Sliver就是一條可以滾動的內容。Slivers應該被放到一個ScrollView Widget內,CustomScrollView是創建ScrollView的基礎類,它的children可以是一組Slivers。
Flutter提供了多種Slivers,以下是創建列表常用到的幾個Slivers:
- SliverAppBar:被用於創建可摺疊的AppBar
- SliverList:線性列表
- SliverFixedExtentList:和上一個類似,只不過行高固定
- SliverToBoxAdapter:包含一個指定大小子部件的Sliver
- SliverPadding:可以用於為Sliver指定padding值
我們這裡使用到了SliverChildBuildDelegate,它成為Slivers代理,負責創建包含子部件的Sliver。
修改後的代碼如下:
@override
Widget build(BuildContext context) {
return new Expanded(
child: new Container(
color: new Color(0xff736ab7),
child: new CustomScrollView(
scrollDirection: Axis.vertical, // 豎直方向滾動
slivers:
new SliverPadding(
padding: const EdgeInsets.symmetric(vertical: 24.0),
sliver: new SliverFixedExtentList(
delegate: new SliverChildBuilderDelegate(
(context, index) => new PlanetRow(planets[index]),
childCount: planets.length,
),
itemExtent: 152.0),
)],),));
}
運行項目
完成後點擊Hot reload,iPhone8模擬器效果如下:
項目地址
[email protected]:hao2008/flutter-demo.git
下篇預告
行星之路由/導航
歡迎關注『郝先生談技術』頭條號,您的關注,是對作者最大的鼓勵,也是作者創作的動力。
閱讀更多 郝先生談技術 的文章