Flutter ListView控件

        ListView是flutter中线性排列的可滚动的列表部件。ListView 是最常用的滚动小部件。它在滚动方向上一个接一个地显示其子项。在交叉轴上,子项需要填满 ListView。 

        如果非空,则 itemExtent 会强制子项在滚动方向上具有给定的范围。

        如果非空,则prototypeItem 会强制子项在滚动方向上具有与给定小部件相同的范围。 指定 itemExtent 或prototypeItem 比让子项确定自己的范围更有效,因为滚动机制可以利用对子项范围的预知来节省工作,例如当滚动位置发生剧烈变化时。 您不能同时指定 itemExtent 和prototypeItem,只能指定其中一个或不指定其中任何一个。

        构建 ListView 有四种选项

        1.默认构造函数采用显式 List<Widget> 子项

        此构造函数适用于子项数量较少的列表视图,因为构造 List 需要为列表视图中可能显示的每个子项(而不仅仅是实际可见的子项)执行工作。默认 List 方式,是把数据添加到列表中,然后直接添加到 ListView。   Tips: 如果需要设置分割线,使用ListTile.divideTiles。

 child: ListView(
          padding: const EdgeInsets.all(8),
          children: <Widget>[
            Container(
              height: 50,
              color: Colors.amber[600],
              child: const Center(child: Text("Entry A")),
            ),
            Container(
              height: 50,
              color: Colors.amber[500],
              child: const Center(child: Text("Entry B")),
            ),
            Container(
              height: 50,
              color: Colors.amber[100],
              child: const Center(child: Text("Entry C")),
            )
          ],
        )

        2.ListView.builder 构造函数采用 IndexedWidgetBuilder,它根据需要构建子项

        此构造函数适用于子项数量较多(或无限)的列表视图,因为仅对实际可见的子项调用构建器。

 child: ListView.builder(
          controller: _scrollController,
          itemBuilder: (context, index) {
            return Card(
              child: Container(
                height: 60,
                alignment: Alignment.centerLeft,
                child: Text("Item $index"),
              ),
            );
          },
          itemCount: 200,
        ),

 如果要添加分割线可以通过一个Column包裹Container和一个Divider。

    child: ListView.builder(
          controller: _scrollController,
          itemBuilder: (context, index) {
            return Card(
              child:Column(
                children: [
                Container(
                    height: 60,
                    alignment: Alignment.centerLeft,
                    child: Text("Item $index"),
                  ),
                  new Divider()
                ],
              ),
            );
          },

        3.ListView.separated 构造函数采用两个 IndexedWidgetBuilder:itemBuilder 根据需要构建子项,separatorBuilder 类似地构建出现在子项之间的分隔符子项

此构造函数适用于子项数量固定的列表视图。通过 separatorBuilder 直接添加分割线。

  final List<String> entries = <String>['C', 'Y', 'Z', 'Y'];
  final List<int> colorCodes = <int>[600, 500, 300, 100];

 
 child: ListView.separated(
            itemBuilder: (BuildContext context, int index) {
              return Container(
                height: 50,
                color: Colors.amber[colorCodes[index]],
                child: Center(child: Text('Entry ${entries[index]}')),
              );
            },
            separatorBuilder: (context, index) {
              return const Divider();
            },
            itemCount: entries.length),

4.ListView.custom 构造函数采用 SliverChildDelegate,它提供了自定义子模型其他方面的功能。

例如,SliverChildDelegate 可以控制用于估计实际不可见的子项大小的算法。

List<String> entries = <String>['C', 'Y', 'Z', 'Y'];

class KeepAliveItem extends StatelessWidget {
  const KeepAliveItem({
    required Key super.key,
    required this.data,
  });

  final String data;

  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      child: Text(data),
    );
  }
}

    child: ListView.custom(
            childrenDelegate: SliverChildBuilderDelegate(
          (BuildContext context, int index) {
            return KeepAliveItem(
              data: entries[index],
              key: ValueKey<String>(entries[index]),
            );
          },
          childCount: entries.length,
        ))

 

ScrollController

要控制滚动视图的初始滚动偏移,请提供一个已设置其 ScrollController.initialScrollOffset 属性的控制器(ScrollController)。

ScrollController:可用于控制此滚动视图滚动到的位置的对象。

ScrollController.initialScrollOffset:控制初始滚动位置。

  final ScrollController _scrollController = ScrollController(initialScrollOffset: 120);

  child: ListView.builder(
          controller: _scrollController,
          itemBuilder: (context, index) {
            return Card(
              child: Column(
                children: [
                  Container(
                    height: 60,
                    alignment: Alignment.centerLeft,
                    child: Text("Item $index"),
                  ),
                  new Divider()
                ],
              ),
              // child: Container(
              //   height: 60,
              //   alignment: Alignment.centerLeft,
              //   child: Text("Item $index"),
              // ),
            );
          },
          itemCount: 200,
        )

效果如下,打开时会有120的偏移:(Item0上移了)

ScrollController.keepScrollOffset:用于控制滚动视图是否应自动保存和恢复其在 PageStorage 中的滚动位置。每次滚动完成时,使用 PageStorage 保存当前滚动偏移量,如果重新创建此控制器的可滚动项,则恢复它。

ScrollController.offset:用于读取当前滚动位置或更改它。(可以动态获取偏移量)

  final ScrollController _scrollController = ScrollController();


 _scrollController.addListener(() {
      setState(() {
        offset = _scrollController.offset;
        isEnd = _scrollController.position.pixels ==
            _scrollController.position.maxScrollExtent;
      });
    });



 child: ListView.builder(
          controller: _scrollController,
          itemBuilder: (context, index) {
            return Card(
              child: Column(
                children: [
                  Container(
                    height: 60,
                    alignment: Alignment.centerLeft,
                    child: Text("Item $index"),
                  ),
                  new Divider()
                ],
              ),
              // child: Container(
              //   height: 60,
              //   alignment: Alignment.centerLeft,
              //   child: Text("Item $index"),
              // ),
            );
          },
          itemCount: 200,
        )

 如下图所示:position:114 表示上滑过程中计算出来的偏移量。

子元素的生命周期

Creation

在布局列表时,可见子元素、状态和渲染对象将基于现有小部件(例如使用默认构造函数时)或延迟提供的小部件(例如使用 ListView.builder 构造函数时)延迟创建。

Destruction

当子元素滚动出视图时,关联的元素子树、状态和渲染对象将被销毁。当滚动回时,列表中相同位置的新子元素将与新元素、状态和渲染对象一起延迟重新创建。

Destruction mitigation

        

        

        

        

        

        

        

        

        

参考:https://api.flutter.dev/flutter/widgets/ListView-class.html?_gl=1*1kk33gn*_ga*NjkxNDYxMjU2LjE3MTMyMzA4MTE.*_ga_04YGWK0175*MTcyNDMzMDgzMi4xNi4xLjE3MjQzMzA5MTcuMC4wLjA.

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值