Flutter - ListView與GridView

歡迎關注微信公衆號:FSA全棧行動 👋前端

1、ListView

  • ListView(): 當 children 比較明確, 數量較少的時候可使用, 列表 item 一次性所有加載
  • ListView.builder(): children 數量較多的時候使用, 在 item 即將展現出來的時候纔會被建立
  • ListView.separated(): 比 ListView.builder()多了分割線功能

一、ListView()

經過 ListView() 默認構造器建立出來的列表, 會一次性加載所有的 item, 是比較消耗性能的, 在列表 item 個數明確只有較少的情景下可使用, 常見參數有:微信

  • scrollDirection: 列表滾動方向, 默認是縱向, 可使用 Axis.horizontal 改成橫向
  • itemExtent: item 在 scrollDirection 方向上的尺寸, 若是列表是縱向, 則設置的是 item 的高度, 若是列表是橫向, 則設置的是 item 的寬度
  • reverse: 逆向排序, 默認爲正向(false)
  • children: 列表中全部的子 widget, 若是 item 類型一致, 能夠藉助 List.generate() 批量建立
class ListViewDemo1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      // scrollDirection: Axis.horizontal, // 滾動方向
      // itemExtent: 100, // item在scrollDirection方向上的尺寸
      reverse: true,
      children: List.generate(100, (index) {
        // return Text("Hello lqr : $index", style: TextStyle(fontSize: 30));
        return ListTile(
          leading: Icon(Icons.people),
          trailing: Icon(Icons.delete),
          title: Text("聯繫人$index"),
          subtitle: Text("聯繫人電話號碼:18812345678"),
        );
      }),
    );
  }
}
複製代碼

二、ListView.builder()

使用 ListView 的命名構造函數 builder() 建立出來的列表, 只有當 item 須要展現時纔會建立加載(調用 itemBuilder 函數), 適用於有大量數據的列表場景, 常見參數以下:markdown

  • itemCount: 列表的 item 數量, 不指定則有無限個 item
  • itemExtent: item 在 scrollDirection 方向上的尺寸, 若是列表是縱向, 則設置的是 item 的高度, 若是列表是橫向, 則設置的是 item 的寬度
  • itemBuilder: 用於建立 item 的函數, (BuildContext context, int index){}

itemBuilder 的函數類型定義是: typedef IndexedWidgetBuilder = Widget Function(BuildContext context, int index);less

class ListViewDemo2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: 100,
      itemExtent: 60,
      itemBuilder: (BuildContext context, int index) {
        return Text("Hello lqr: $index", style: TextStyle(fontSize: 20));
      },
    );
  }
}
複製代碼

三、ListView.separated()

使用 ListView 的命名構造函數 separated() 建立列表與 builder() 同樣, 都是按需建立加載 item, 區別在於 separated() 能夠繪製分割線, 常見屬性以下:dom

  • separatorBuilder: 用於建立分割線的函數, (BuildContext context, int index){}

separatorBuilder 的函數類型定義是: typedef IndexedWidgetBuilder = Widget Function(BuildContext context, int index);ide

通常使用 Divider 這個 widget 來建立分割線, 其構造函數參數有:函數

  • Divider
    • color: 分割線顏色
    • height: Divider 自己的佔用的高度 (注意:不是分割線的厚度)
    • thickness: 分割線的厚度
    • indent: 分割線前端的空隙
    • endIndent: 分割線末端的空隙
class ListViewDemo3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView.separated(
      itemCount: 100,
      itemBuilder: (BuildContext context, int index) {
        return Text("Hello lqr: $index", style: TextStyle(fontSize: 20));
      },
      separatorBuilder: (BuildContext context, int index) {
        return Divider(
          color: Colors.red,
          height: 40, // widget的高度
          thickness: 10, // 分割線的厚度
          indent: 10, // 分割線前端的空隙
          endIndent: 30, // 分割線末端的空隙
        );
      },
    );
  }
}
複製代碼

2、GridView

  • GridView(): 列表 item 一次性所有加載
  • GridView.count(): 是 GridView() + SliverGridDelegateWithFixedCrossAxisCount 的簡寫
  • GridView.extent(): 是 GridView() + SliverGridDelegateWithMaxCrossAxisExtent 的簡寫
  • GridView.builder(): 當 item 將顯示的時候建立

一、GridView()

使用 GridView 默認構造函數建立的網格會一次性加載全部 item, 適用於 item 個數較少的場景, 能夠把 GridView 理解爲是能夠有多列的 ListView, 當有行有列時, 就會有定製行列樣式的需求, 由參數 gridDelegate 來配置, gridDelegate 的類型是 SliverGridDelegate, 該抽象類有 2 個實現類:oop

  • SliverGridDelegateWithFixedCrossAxisCount: 交叉軸固定 item 個數 (幾列咱們本身定)
  • SliverGridDelegateWithMaxCrossAxisExtent: 交叉軸上 item 最大範圍 (幾列交給 flutter 算)

gridDelegate: 網格代理, 用於控制子 widget 在 GridView 中的擺放性能

SliverGridDelegateWithFixedCrossAxisCount 常見參數有:ui

  • crossAxisCount: 交叉軸 item 個數 (若是網格是縱向, 則指定網格有幾列, 反之則指定網格有幾行)
  • childAspectRatio: item 的寬高比
  • crossAxisSpacing: 交叉軸 item 間空隙 (縱向: 列間距)
  • mainAxisSpacing: 主軸 item 間空隙 (縱向: 行間距)
class GridViewDemo1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    /// SliverGridDelegateWithFixedCrossAxisCount: 交叉軸固定item個數(幾列咱們本身定)
    /// 簡寫: GridView.count(crossAxisCount: 3)
    return GridView(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 3,
        childAspectRatio: .8, // ratio = 寬度 / 高度
        crossAxisSpacing: 8,
        mainAxisSpacing: 8,
      ),
      children: List.generate(100, (index) {
        return Container(
          color: Color.fromARGB(
            255,
            Random().nextInt(256),
            Random().nextInt(256),
            Random().nextInt(256),
          ),
        );
      }),
    );
  }
}
複製代碼

SliverGridDelegateWithMaxCrossAxisExtent 常見參數有:

  • maxCrossAxisExtent: 交叉軸上 item 最大範圍 (縱向: Flutter 會根據屏幕寬度 與 item 最大範圍自動計算出列數)
  • childAspectRatio: item 的寬高比
  • crossAxisSpacing: 交叉軸 item 間空隙 (縱向: 列間距)
  • mainAxisSpacing: 主軸 item 間空隙 (縱向: 行間距)
class GridViewDemo2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GridView(
      /// SliverGridDelegateWithMaxCrossAxisExtent: 交叉軸上item最大範圍(幾列交給flutter算)
      /// 簡寫: GridView.extent(maxCrossAxisExtent: 400)
      gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
        maxCrossAxisExtent: 400,
        mainAxisSpacing: 8,
        crossAxisSpacing: 8,
        childAspectRatio: 1.8,
      ),
      itemCount: 100,
      children: List.generate(100, (index) {
        return Container(
          color: Color.fromARGB(
            255,
            Random().nextInt(256),
            Random().nextInt(256),
            Random().nextInt(256),
          ),
        );
      }),
    );
  }
}
複製代碼

二、GridView.builder()

使用 GridView 命名構造函數 builder() 建立的網格會按需建立加載 item, 適用於有大量的數據展現場景, 常見參數有:

  • gridDelegate: 網格代理, 用於控制子 widget 在 GridView 中的擺放, 類型是 SliverGridDelegate, 經常使用子類有:
    • SliverGridDelegateWithFixedCrossAxisCount
    • SliverGridDelegateWithMaxCrossAxisExtent
  • itemCount: 網格的 item 數量, 不指定則有無限個 item
  • itemBuilder: 用於建立 item 的函數, (BuildContext context, int index){}

itemBuilder 的函數類型定義是: typedef IndexedWidgetBuilder = Widget Function(BuildContext context, int index);

class GridViewDemo3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
      itemCount: 100,
      itemBuilder: (BuildContext context, int index) {
        return Container(
          color: Color.fromARGB(255, Random().nextInt(256),
              Random().nextInt(256), Random().nextInt(256)),
        );
      },
    );
  }
}
複製代碼

若是文章對您有所幫助, 請不吝點擊關注一下個人微信公衆號:FSA全棧行動, 這將是對我最大的激勵. 公衆號不只有Android技術, 還有iOS, Python等文章, 可能有你想要了解的技能知識點哦~

相關文章
相關標籤/搜索