Flutter 基礎(七)Scrolling Widget 之 ListView、GridView、PageView

NiZerin發表於2019-06-18

Flutter基礎(七)Scrolling Widget之ListView、GridView、PageView

前言

我們知道Widget的分類有很多種,比如:Basics、Material Components、Cupertino、Scrolling等等,在前面的文章我介紹了Basics和Material Components,這一篇講一下Scrolling分類中比較常用的ListView、GridView、PageView。

1 ListView

ListView可以說是Flutter中最常用的Scrolling Widget。
ListView有四種建構函式:

  1. 預設建構函式ListView。
  2. ListView.builder,適用於具有大量(或無限)列表項。
  3. ListView.separated,可以配置分割線,適用於具有固定數量列表項的ListView。
  4. ListView.custom,提供了自定義子Widget的能力。

1.1 預設建構函式

用預設建構函式的方式來實現一個簡單的列表。


import 'package:flutter/material.dart';

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
 return MaterialApp(
 title: 'Flutter',
 home: Scaffold(
 appBar: AppBar(
 title: Text('ListView示例'),
 ),
 body: ListView(
 children: <Widget>[
 ListTile(
 leading: Icon(Icons.access_time),
 title: Text('第1行'),
 ),
 ListTile(
 leading: Icon(Icons.access_time),
 title: Text('第2行'),
 ),
 ],
 ),
 ),
 );
 }
}

ListTile是Material Components中的Widget,通常用於填充ListView,可以滿足基本的圖片+文字的列表需求。
VwPmwj.png

1.2 ListView.builder建立

如果要展示大量列表項,可以使用ListView.builder。


import 'package:flutter/material.dart';

void main() => runApp(MyApp(
 items: new List<String>.generate(300, (i) => "第$i行"), //1
 ));

class MyApp extends StatelessWidget {
 final List<String> items;

 MyApp({@required this.items});
 @override
 Widget build(BuildContext context) {
 return MaterialApp(
 title: 'Flutter',
 home: Scaffold(
 appBar: AppBar(
 title: Text('ListView示例'),
 ),
 body: ListView.builder( //2
 itemCount: items.length,
 itemBuilder: (context, index) {
 return ListTile(
 leading: Icon(Icons.access_time),
 title: Text('${items[index]}'),
 );
 },
 ),
 ),
 );
 }
}

在註釋1生成300個資料,並將其傳入到MyApp中,註釋2處通過ListView.builder建立ListView,最終會通過ListTile來顯示每一個列表項。
VwP86U.png

1.3 ListView.separated建立


import 'package:flutter/material.dart';

void main() => runApp(MyApp(
 items: new List<String>.generate(300, (i) => "第$i行"), 
 ));

class MyApp extends StatelessWidget {
 final List<String> items;

 MyApp({@required this.items});

 @override
 Widget build(BuildContext context) {
 return MaterialApp(
 title: 'Test',
 home: Scaffold(
 appBar: AppBar(
 title: Text('ListView示例'),
 ),
 body: ListView.separated(
 itemCount: items.length,
 itemBuilder: (context, index) {
 return ListTile(
 leading: Icon(Icons.access_time),
 title: Text('${items[index]}'),
 );
 },
 separatorBuilder: (context, index) {//1
 return Container(
 constraints: BoxConstraints.tightFor(height: 1),
 color: Colors.black45,
 );
 },
 ),
 ),
 );
 }
}

這種建立方式和ListView.builder類似,有個最大的不同就是可以通過註釋1處的separatorBuilder來設定分割線以及分割線的樣式。
VwDsxA.png

2 GridView

GridView的使用方法和ListView類似,它有五種建構函式:

  1. 預設建構函式GridView。
  2. GridView.count:在橫軸方向上具有固定數量的GridView。
  3. GridView.extent:在橫軸方向上具有最大範圍的GridView。
  4. GridView.builder:適用於具有大量(或無限)列表項。
  5. GridView.custom:提供了自定義子Widget的能力。

這裡以第2種建構函式為例。


import 'package:flutter/material.dart';

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
 return MaterialApp(
 title: 'Flutter',
 home: Scaffold(
 appBar: AppBar(
 title: new Text('GridView示例'),
 ),
 body: GridView.count(
 crossAxisCount: 3, //1
 children: <Widget>[
 ListTile(
 title: Text('item1'),
 ),
 ListTile(
 title: Text('item2'),
 ),
 ListTile(
 title: Text('item3'),
 ),
 ListTile(
 title: Text('item4'),
 ),
 ListTile(
 title: Text('item5'),
 ),
 ListTile(
 title: Text('item6'),
 ),
 ListTile(
 title: Text('item7'),
 ),
 ListTile(
 title: Text('item8'),
 ),
 ListTile(
 title: Text('item9'),
 ),
 ],
 ),
 ),
 );
 }
}

註釋1處的crossAxisCount用於設定橫軸item的數量。效果如下圖所示:
VBCOyT.png

3 PageView

PageView是一個可逐頁滾動的列表,和Android中ViewPage類似。
PageView有三種建構函式:

  1. 預設建構函式PageView
  2. PageView.builder:適用於具有大量(或無限)列表項。
  3. PageView.custom:提供了自定義子Widget的能力。

以預設建構函式為例,程式碼如下所示。


import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
 return MaterialApp(
 title: 'Flutter',
 home: Scaffold(
 appBar: AppBar(
 title: Text('PageView示例'),
 ),
 body: PageView(
 onPageChanged: (index) {//1
 print('當前為第 $index 頁');
 },
 children: <Widget>[
 ListTile(
 title: Text('第0頁'),
 ),
 ListTile(
 title: Text('第1頁'),
 ),
 ListTile(
 title: Text('第2頁'),
 ),
 ],
 ),
 ),
 );
 }
}

通過註釋1處的onPageChanged屬性可以得知當前滑動到了第幾頁。
VBk9Yj.png

總結

本文並沒有介紹每個Widget的建構函式,那樣的話就不是一篇文章能寫下的了,也沒有必要,我們掌握了其中一種建構函式基本就可以舉一反三了。Scrolling Widget還包含了一些其他Widget,比如:NestedScrollView、Scrollbar、CustomScrollView、NotificationListener等等,就需要去自行檢視官方文件了:https://flutter.dev/docs/development/ui/wi...


By: Laravel-China 寧澤林
MyBlog: nizer.in

相關文章