使用 flutter 的ListView實現滾動列表

流汗去發表於2018-12-28

現如今開啟一個 App,比如頭條、微博,都會有長列表,隨著我們不斷地滑動,視窗內的內容也會不斷地更新。今天就用 Flutter 實現一下這種效果。

使用 flutter 的ListView實現滾動列表


這裡的表現其實就相當於有一個固定長度的容器,然後超出的內容是不可見的,只有當你向上或向下滑動螢幕時,視窗外看不見的內容才會出現在視窗中。如果在 web 開發時,是需要容器加上樣式

overflow: auto;
複製程式碼

要想用 Flutter 實現,其實也是很簡單的,因為 Flutter 為我們提供了 ListView 元件。

ListView 主要有以下幾種使用方式

  • ListView
  • ListView.builder
  • ListView.separated
  • ListView.custom

ListView

ListView 是最簡單直接的方式,簡單,那麼適用的場景也是簡單的。僅適用於內容較少的情形,因為它是一次性渲染所有的 items ,當 items 的數目較多時,很容易出現卡頓現象的,導致滑動不流暢。 你可以試試加大下面 items 的大小,然後對比一下體驗效果。

class ListViewDemo extends StatelessWidget {
  final _items = List<Widget>.generate(10,
      (i) => Container(padding: EdgeInsets.all(16.0), child: Text("Item $i")));

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: _items,
    );
  }
}

複製程式碼

ListView.builder()

建構函式 builder 要求傳入兩個引數,itemCountitemBuilder 。前者規定列表數目的多少,後者決定了每個列表如何渲染。跟 ListView 不同的點在於,這是懶載入的,假如有 1000 個列表,初始渲染時並不會所有都渲染,而只會特定數量的 item ,這對於效能和使用者體驗來說,是很好的提升。 你可以對比用 ListView 和用 ListView.builder 渲染 1000 個列表時,體驗是否有差別。

class ListViewDemo extends StatelessWidget {
  final _items = List<String>.generate(1000, (i) => "Item $i");

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: 1000,
      itemBuilder: (context, idx) {
        return Container(
          padding: EdgeInsets.all(16.0),
          child: Text(_items[idx]),
        );
      },
    );
  }
}
複製程式碼

ListView.separated()

separated 相比較於 builder,又多了一個引數 separatorBuilder ,用於控制列表各個元素的間隔如何渲染。比如,我們需要列表的每個 item 之間有一個分割線,就可以跟下面那樣,加一個 Divider 元件。

class ListViewDemo extends StatelessWidget {
  final _items = List<String>.generate(1000, (i) => "Item $i");

  @override
  Widget build(BuildContext context) {
    return ListView.separated(
      itemCount: 1000,
      itemBuilder: (context, idx) {
        return Container(
          padding: EdgeInsets.all(16.0),
          child: Text(_items[idx]),
        );
      },
      separatorBuilder: (context, idx) {
        return Divider();
      },
    );
  }
}
複製程式碼

ListView.custom()

custom,就跟名字一樣,讓我們自定義。必須的引數就是 childrenDelegate , 然後傳入一個 實現了 SliverChildDelegate 的元件,如 SliverChildListDelegateSliverChildBuilderDelegate

SliverChildListDelegate 接收跟 ListView 一樣的 children,而 SliverChildBuilderDelegate 接收跟 ListView.builder 的 itemBuilder 一樣型別的函式。

正常來說,前面三個已經可以滿足我們的日常使用需求了,無需自定義。


總結,上面主要討論了 ListView 的幾個建構函式及用法,討論如何實現常見的滾動列表。

完成的程式碼,可見 list_view.dart


最後

筆者最近在學習flutter,會持續地記錄自己的學習過程,並放在 github 上。

有問題歡迎提出,大家一起討論,一起進步。

參考資料

Flutter ListView and ScrollPhysics: A Detailed Look

ListView class

相關文章