Flutter 中 ListView 的 4 种构建方式详解 | Flutter Widgets

6,250 阅读2分钟

这是我参与更文挑战的第7天,活动详情查看: 更文挑战

前言

ListView 是 Flutter 最常用的列表组件之一,今天我们一起来看看他的 4 种构建方式,以及构建时有哪些实践技巧,帮助我们快速有效的学习。
02.gif

第一种 - ListView 构造

先看看源码

image.png
这里我们需要传递一个 Widget 类型的列表即可,最终实现是由 SliverChildListDelegate 创建的 childrenDelegate
image.png
最后构建子项目的时候是还是由一个叫 SliverList 构建的,这里我们不展开聊,之后会聊这个,看完后关注专栏之后聊

怎么使用?

看了源码我们来看看使用就简单了,只需要构建一个 List<Widget> 传入到 children 即可。

这里我们使用 List.generate 生成长度为 100 的列表,然后构建成 List<Widget>

ListView(
  // 生成长度为 100 的列表
  children: List.generate(100, (index) {
    return getItem(index);
  }),
)

image.png

看看 getItem 实现

  • 使用 Flutter 中 ListTile 可以快速构建一个列表项

因为是模拟数据,这里取余一下

/// 获取子项目
Widget getItem(int index) {
  // 获取数据
  var item = listData[index % 5];
  // 构建列表项
  return ListTile(
    // 前部图片
    leading: Image.network(
      item.url,
      width: 80,
      height: 60,
      fit: BoxFit.cover,
    ),
    // 标题
    title: Text(item.title),
    // 副标题
    subtitle: Text(item.desc),
    // 后部箭头
    trailing: Icon(Icons.keyboard_arrow_right_outlined),
    onTap: () {
      print('index');
    },
    onLongPress: () {
      print('${item.desc}');
    },
  );
}

添加分割线

看上图是没有添加分割线的,我们只需要使用 ListTile.divideTiles 即可添加上分割线啦

ListView(
  children: ListTile.divideTiles(
    context: context,
    tiles: List.generate(100, (index) {
      return getItem(index);
    }),
  ).toList(),
)

03.png

第二种 - ListView.separated 构建

说到分割线我们不得不说说第二种构建方式了,来看看他怎么使用吧,这也是另外一个种最常用的构建分隔线的方法

ListView.separated(
  itemBuilder: (context, index) {
    return getItem(index);
  },
  // 奇数有分割线
  separatorBuilder: (context, index) =>
  index.isOdd ? Divider(height: 10) : SizedBox(),
  // 80 个数量
  itemCount: 80,
)

04.png

相比之前这里我们使用分隔符构建起

第三种 - ListView.builder 构建

这种也是我们最常用的,使用起来也非常的简单

ListView.builder(
  itemBuilder: (context, index) {
    return getItem(index);
  },
  itemCount: 20,
)

滚动方向

列表类 Widget 都有一个重要的属性 scrollDirection 可以控制滚动的方向,方便我们根据需要调整方向

  • Axis.vertical 纵向(默认)
  • Axis.horizontal 横向
ListView.builder(
  // 设置横向滚动
  scrollDirection: Axis.horizontal,
  itemBuilder: (context, index) {
    return SizedBox(
      width: 300,
      child: getItem(index),
    );
  },
  itemCount: 20,
)

03.gif

第四种 - ListView.custom 构建

开始我们查看了源码,现在来看这第四种方式,是不是就很显而易见了,这里我们使用了 SliverChildBuilderDelegate 这个之后我们也会详细聊到

ListView.custom(
  childrenDelegate: SliverChildBuilderDelegate(
    (BuildContext context, int index) {
      return getItem(index);
    },
    childCount: 100,
  ),
)

源码仓库

基于 Flutter 🔥 最新版本

参考链接

关注专栏

  • 此文章已收录到下面👇 的专栏,可以直接关注
  • 更多文章继续阅读|系列文章持续更新

👏 欢迎点赞➕收藏➕关注,有任何问题随时在下面👇评论,我会第一时间回复哦