ListView是在Flutter中常見的具有滾軸的Widget。在做大量資料顯示時,例如像是圖片,文章,文字列表時,通常都會使用ListView來大量重複的相似的介面。你可以做直向滾動的ListView,也可以做橫向滾動的ListView,這些都是根據設計者的需求來決定。
這裡先介紹簡單的ListView的使用方法。
先從下面ListView的構造函數來看看,可以對ListView做哪些設定。
ListView({
Key key,
Axis scrollDirection: Axis.vertical,
bool reverse: false,
ScrollController controller,
bool primary,
ScrollPhysics physics,
bool shrinkWrap: false,
EdgeInsetsGeometry padding,
double itemExtent,
bool addAutomaticKeepAlives: true,
bool addRepaintBoundaries: true,
bool addSemanticIndexes: true,
double cacheExtent,
List<Widget> children: const [],
int semanticChildCount,
DragStartBehavior dragStartBehavior: DragStartBehavior.start
})
預設上,ListView是垂直方向的滾動列表。可以透過 scrollDirection 來做設定。 列表上的元素則是由 children 來做控制。一般來說,都是設定一組相似的UI List。
以下一個簡單的例子來顯示一個垂直滾動的列表。
ListView(
children: <Widget>[
Container(
height: 50,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 50,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
],
)
除了像上面例子那樣直接用ListView之外,也可以用 ListView.builder 來製作列表。 先看看構造函數。
ListView.builder({
Key key,
Axis scrollDirection: Axis.vertical,
bool reverse: false,
ScrollController controller,
bool primary, ScrollPhysics physics,
bool shrinkWrap: false,
EdgeInsetsGeometry padding,
double itemExtent,
@required IndexedWidgetBuilder itemBuilder,
int itemCount,
bool addAutomaticKeepAlives: true,
bool addRepaintBoundaries: true,
bool addSemanticIndexes: true,
double cacheExtent,
int semanticChildCount,
DragStartBehavior dragStartBehavior: DragStartBehavior.start
})
從上發現@required IndexedWidgetBuilder itemBuilder
這個屬性,故得知使用ListView.builder時必須設定 itemBuilder。
下面給了一個簡單的例子。
ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Text(index.toString());
}),
可以想像一下,當有一筆要顯示的數據時,使用ListView.builder的方式,只要在itemBuilder裡定義返回一個列表的項目UI後,它會按照定義去自動重複生成剩下的項目UI。
當然,也可以用ListView加上自製的重複生成UI的處理也可以做得到,而ListView.builder的方法中已經包含了重複生成UI的處理了,使用起來較為方便一點。
另外,根據官方網站上的描述,當製作大量的資料的列表時,推薦使用這個方法,因為他會在項目要顯示在螢幕時去呼叫builder,而非事先做好大量的項目,這樣可以節省負擔更加有效率。
This constructor is appropriate for list views with a large (or infinite) number of children because the builder is called only for those children that are actually visible.
稍微注意一下,上面的例子會產生一個無限項目的列表,也就是可以一直向下滾動列表,可以設定 itemCount的值來決定列表內項目的最大數目。
某些場合,會需要各個項目之間能有個分隔的效果,像是一條分隔線。這個時候可以考慮使用 ListView.separated。
照樣先來看一下構造函數。
ListView.separated({
Key key,
Axis scrollDirection: Axis.vertical,
bool reverse: false,
ScrollController controller,
bool primary,
ScrollPhysics physics,
bool shrinkWrap: false,
EdgeInsetsGeometry padding,
@required IndexedWidgetBuilder itemBuilder,
@required IndexedWidgetBuilder separatorBuilder,
@required int itemCount,
bool addAutomaticKeepAlives: true,
bool addRepaintBoundaries: true,
bool addSemanticIndexes: true,
double cacheExtent })
與ListView.builder相比較一下,可以發現使用這個方法時,不只itemBuilder要定義,itemCount也成了必須指定的屬性,另外還要用 separatorBuilder 設定分隔UI。
以下給出一個簡單的例子。
ListView.separated(
itemCount: entries.length,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 50,
color: Colors.amber[colorCodes[index]],
child: Center(child: Text('Entry ${entries[index]}')),
);
},
separatorBuilder: (BuildContext context, int index) => const Divider(),
);
ListView是個不可或缺的UI。這次簡單地了解了垂直列表的作法,下次想嘗試看看橫向列表的製作方式。如此才能因應不同場合製作出合適的列表UI。