Flutter列表视图ListView的4种创建方式及使用实例

本文介绍了Flutter中ListView的4种创建方法:直接使用构造函数、ListView.builder、ListView.separated及ListView.custom。每种方法都有其适用场景,如builder适合创建大型列表并支持懒加载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Flutter列表视图ListView的4种创建方式及使用实例


ListView 是一个线性布局的widgets列表,可以使用水平布局,也可以使用垂直布局(默认)。

接下来我们来看如何在Flutter中创建和使用ListView。

创建ListView

我们可以使用多种方式创建ListView对象。

1. 直接使用ListView的构造函数

默认构造函数有一个children参数,它接受一个Widget数组列表(List)。

这种方式适合只有少量的子组件的情况,因为这种方式需要将所有子widget都提前创建好,而不是等到子widget真正显示的时候再创建,也就是说通过默认构造函数构建的ListView没有应用基于Sliver的懒加载模型。如果列表长度非常长,直接创建大量子widget可能会引起内存问题。

使用 ListView(children: List) 的优点是简单,直接生成一个 List 的列表,然后赋值给 ListView 的 children 参数即可,例如:

List<Widget> getListChildren() {
  return [new Text("第一条"), new Text("第二条"), new Text("第三条")];
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: new ListView(
        children: getListChildren(),
        shrinkWrap: true,
        padding: const EdgeInsets.all(25.0),
        itemExtent: 50,
      ),
    );
  }
}

我们来看ListView的构造函数:

  ListView({
    Key key,
    Axis scrollDirection = Axis.vertical,//列表的滚动方向,默认是垂直方向
    bool reverse = false,
    ScrollController controller,//控制器,与列表滚动相关,比如监听列表的滚动事件
    bool primary,
    ScrollPhysics physics,//列表滚动至边缘后继续拖动的物理效果,Android与iOS效果不同。
    bool shrinkWrap = false,//该属性将决定列表的长度是否仅包裹其内容的长度。当ListView嵌在一个无限长的容器组件中时,shrinkWrap必须为true,否则Flutter会给出警告
    EdgeInsetsGeometry padding,//列表内边距
    this.itemExtent,//子元素长度。当列表中的每一项长度是固定的情况下可以指定该值,有助于提高列表的性能
    bool addAutomaticKeepAlives = true,
    bool addRepaintBoundaries = true,
    bool addSemanticIndexes = true,
    double cacheExtent,//预渲染区域长度,ListView会在其可视区域的两边留一个cacheExtent长度的区域作为预渲染区域(对于ListView.build或ListView.separated构造函数创建的列表,不在可视区域和预渲染区域内的子元素不会被创建或会被销毁)
    List<Widget> children = const <Widget>[],//子元素的数组列表
    int semanticChildCount,
    DragStartBehavior dragStartBehavior = DragStartBehavior.start,
    ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
  })

可以看到,使用构造函数创建ListView还是非常简单的,但只适用于列表元素较少的情况。

2. ListView.builder

ListView.builder利用IndexedWidgetBuilder来按需构造。这种方式适合于具有大量(或无限)子视图的列表视图(因为它只创建当前可见的列表元素)。也就说通过该构造函数创建的ListView是支持基于Sliver的懒加载模型的。

方法及参数:

  ListView.builder({
    Key key,
    Axis scrollDirection = Axis.vertical,
    bool reverse = false,
    ScrollController controller,
    bool primary,
    ScrollPhysics physics,
    bool shrinkWrap = false,
    EdgeInsetsGeometry padding,
    this.itemExtent,
    @required IndexedWidgetBuilder itemBuilder,
    int itemCount,
    bool addAutomaticKeepAlives = true,
    bool addRepaintBoundaries = true,
    bool addSemanticIndexes = true,
    double cacheExtent,
    int semanticChildCount,
    DragStartBehavior dragStartBehavior = DragStartBehavior.start,
    ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
  })

ListView.builder 新增了两个重要参数:

  • itemCount:这个参数声明了list的长度,这个值表明ListView中会存在多少个子项,null则表示无限列表。
  • itemBuilder:它是列表项的构建器,类型为IndexedWidgetBuilder,返回值为一个widget。当列表滚动到具体的index位置时,会调用该构建器构建列表项。(接受 context(构造的上下文) 和 index(当前索引) 两个参数)

示例,创建一个无限列表:

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView.builder(
        padding: const EdgeInsets.all(25),
        itemExtent: 50,
        itemBuilder: (context, index) {
          return new Text("第$index行");
        },
      ),
    );
  }
}
3. ListView.separated

如果列表子项之间需要分割线,此时我们可以用ListView的separated方法来创建列表。

函数定义:

  ListView.separated({
    Key key,
    Axis scrollDirection = Axis.vertical,
    bool reverse = false,
    ScrollController controller,
    bool primary,
    ScrollPhysics physics,
    bool shrinkWrap = false,
    EdgeInsetsGeometry padding,
    @required IndexedWidgetBuilder itemBuilder,
    @required IndexedWidgetBuilder separatorBuilder,
    @required int itemCount,
    bool addAutomaticKeepAlives = true,
    bool addRepaintBoundaries = true,
    bool addSemanticIndexes = true,
    double cacheExtent,
    DragStartBehavior dragStartBehavior = DragStartBehavior.start,
    ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
  }) 

ListView.separated可以在生成的列表项之间添加一个分割组件,它采用两个IndexedWidgetBuilder:itemBuilder根据需要构建子项separatorBuilder类似地构建出现在子项之间的分隔符子项。此构造函数适用于具有固定数量的子控件的列表视图。

示例:

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView.separated(
        itemCount: 1000,
        itemBuilder: (context, index) {
          return new Center(child: new Text("第$index行"));
        },
        separatorBuilder: (context, index) {
          return Divider(
            height: 1,
            color: Colors.green,
          );
        },
      ),
    );
  }
}
4. ListView.custom

使用ListView.custom的SliverChildDelegate构造,它提供了定制子模型的其他方面的能力。 例如,SliverChildDelegate可以控制用于估计实际上不可见的孩子的大小的算法。通常我们使用上面介绍的3种方式就足够了,这里对custom不做过多介绍了。

小结

本节我们学习了Flutter中,最常用的视图之一——列表视图的创建及使用方法。

我们可以使用ListView的4种构造方法来创建一个列表视图,并根据自己的需要来进行个性化配置。

ps:如果觉得本文对你有所帮助,请在文章下方 “点赞” 、 “收藏” 一下吧~😁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卜大爷

觉得不错的可以给我加油哦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值