【譯】Flutter進階:深刻探究 ListView 和 ScrollPhysics

Flutter 中的 ListView 能夠對比 Android 中的 ListView 或者 RecycleView(固然也有不一樣之處) ,是可滾動項的線性列表。 咱們能夠用它來製做可滾動項目列表或重複項目列表。html

探究各種型的 ListView

構建 ListView 有如下幾種方式:git

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

ListView

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

代碼的格式爲:微信

ListView(
  children: <Widget>[
    ItemOne(),
    ItemTwo(),
    ItemThree(),
  ],
),
複製代碼

一般這裏應該放少許的子元素,由於 ListView 也會將當前不可見的元素構建起來,所以大量的子元素可能使 App 性能下降。ide

ListView.builder()

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

/images/listview2.gif

代碼的格式爲:性能

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

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

技巧:因爲元素是懶加載的,只加載了所需數量的元素,咱們並不須要將 itemCount 做爲必需參數,列表能夠是無限長的。ui

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

/images/listview3.gif

ListView.separated()

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

/images/listview4.gif

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

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

代碼的格式爲:

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

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

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

/images/listview5.png

**注意:**一般分隔符列表長度比項目列表小 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 中有相似的效果。

/images/listview6.gif

ClampingScrollPhysics

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

/images/listview7.gif

FixedExtentScrollPhysics

該方法與其餘方法略有不一樣,由於它僅適用於 FixedExtendScrollControllers 和使用它們的列表。 舉個例子,咱們用 ListWheelScrollView 來製做相似輪子的列表。

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

/images/listview8.gif

樣例代碼很是簡單:

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 中。

/images/listview9.png

爲何個人 ListView 在列表和外部小部件之間有空格?

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

最後

利用時間整理分析本身所學的知識是件很是有意義的事情,但願這也能幫到其餘正在學習的同窗。同時我也正在用Flutter寫幾個項目,寫好以後就會開源給你們。

Github:github.com/MeandNi

微信:yangjk128

博客:meandni.com/2019/01/26/…

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

參考連接

原英文博客

官方文檔

相關文章
相關標籤/搜索