Flutter進階:深入探究 ListView 和 ScrollPhysics

Flutter 中的 ListView 可以對比 Android 中的 ListView 或者 RecycleView(當然也有不同之處) ,是可滾動項的線性列表。 我們可以用它來製作可滾動項目列表或重複項目列表。

探究各類型的 ListView

構建 ListView 有以下幾種方式:

  1. ListView
  2. ListView.builder
  3. ListView.separated
  4. ListView.custom

ListView

這是 ListView 類的默認構造函數。 ListView 內有任意個數的子元素都可使其滾動。

代碼的格式爲:

ListView(
  children: <Widget>[
    ItemOne(),
    ItemTwo(),
    ItemThree(),
  ],
),

通常這裏應該放少量的子元素,因爲 ListView 也會將當前不可見的元素構建起來,因此大量的子元素可能使 App 性能降低。

ListView.builder()

builder() 構造函數可以用來構造重複的子項列表,這裏我們就可以類比 Android 中的 ListView 。 這個構造函數有兩個主要參數:列表中項目數的 itemCount 和構造每個列表子項的 itemBuilder。

代碼的格式爲:

ListView.builder(
  itemCount: itemCount,
  itemBuilder: (context, position) {
    return listItem();
  },
),

列表項是懶加載的,這表明 Flutter 只構造了特定數量的列表項,當用戶滾動時,早期的列表項被銷燬。

技巧:由於元素是懶加載的,只加載了所需數量的元素,我們並不需要將 itemCount 作爲必需參數,列表可以是無限長的。

ListView.builder(
  itemBuilder: (context, position) {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Text(position.toString(), style: TextStyle(fontSize: 22.0),),
      ),
    );
  },
),

ListView.separated()

在 separate() 的構造函數中,我們同樣生成一個列表,但這裏我們可以指定每個項之間的分隔符。

實質上,這裏,我們構造了兩個交織列表:一個作爲主列表,一個作爲分隔符列表。

要注意的是,這裏不能應用前面構造函數中所說的無限長度,因爲此構造函數會強制執行 itemCount 。

代碼的格式爲:

ListView.separated(
      itemBuilder: (context, position) {
        return ListItem();
      },
      separatorBuilder: (context, position) {
        return SeparatorItem();
      },
      itemCount: itemCount,
),

這種類型的列表允許您動態定義分隔符,爲不同類型的子項分配不同類型的分隔符,在需要時添加或刪除分隔符等。

該實現還可以在列表中方便地插入其他類型的子元素(例如廣告),而不需要對列表項中的主列表進行任何修改。

注意:通常分隔符列表長度比項目列表小 1,因爲在最後一個元素之後不存在分隔符。

ListView.custom()

正如其名,custom() 構造函數允許我們自定義構建 ListViews。 需要的主要參數是 SliverChildDelegate ,用於構建子項。 SliverChildDelegates 的類型是:

  1. verChildListDelegate
  2. SliverChildBuilderDelegate

SliverChildListDelegate 接受一個子項的直接列表,而 SliverChildBuiderDelegate 接受 IndexedWidgetBuilder(我們使用的構造函數)。

您可以使用或子類化這些來構建自己的委託。

ListView 默認構造函數的行爲類似於帶有 SliverChildListDelegate 的 ListView.custom 。

我們已經介紹完了 ListViews 的各種類型,讓我們來看看 ScrollPhysics 。

探究 ScrollPhysics

爲了控制列表滾動的發生方式,我們在 ListView 的構造函數中通常需要設置 physics 參數。 各種類型的 physics 參數有:

NeverScrollablePhysics

NeverScrollablePhysics 表現爲不可滾動的列表。 使用此選項可以完全禁用 ListView 的滾動。

BouncingScrollPhysics

BouncingScrollPhysics 在列表結束時退回列表。 iOS 中有類似的效果。

ClampingScrollPhysics

這是 Android 上使用的默認滾動方式。 列表在結尾處停止並給出一定的效果。

FixedExtentScrollPhysics

該方法與其他方法略有不同,因爲它僅適用於 FixedExtendScrollControllers 和使用它們的列表。 舉個例子,我們用 ListWheelScrollView 來製作類似輪子的列表。

FixedExtentScrollPhysics 僅滾動到子項而不存在任何偏移。

樣例代碼非常簡單:

FixedExtentScrollController fixedExtentScrollController =
    new FixedExtentScrollController();
ListWheelScrollView(
  controller: fixedExtentScrollController,
  physics: FixedExtentScrollPhysics(),
  children: monthsOfTheYear.map((month) {
    return Card(
        child: Row(
      children: <Widget>[
        Expanded(
            child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Text(
            month,
            style: TextStyle(fontSize: 18.0),
          ),
        )),
      ],
    ));
  }).toList(),
  itemExtent: 60.0,
),

你應當知道的其他事情

如何在列表中保留被破壞的元素?

Flutter 提供了一個 KeepAlive() 小組件,它可以使子元素保持活躍狀態,否則會被破壞。 在列表中,默認情況下,元素包裝在 AutomaticKeepAlive 中。

爲什麼我的 ListView 在列表和外部小部件之間有空格?

ListView 在它與外部窗口組件之間有默認填充,將填充設置爲 EdgeInsets.all(0.0) 就可以刪除它。

最後

利用時間整理分析自己所學的知識是件非常有意義的事情,希望這也能幫到其他正在學習的同學。同時我也正在用Flutter寫幾個項目,寫好之後就會開源給大家。

Github:https://github.com/MeandNi

微信:yangjk128

博客:https://meandni.com/2019/01/26/flutter-exploring-list/

歡迎一起交流移動開發的技術!

參考鏈接

原英文博客

官方文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章