SliverChildBuilderDelegate

一个通过`builder`回调函数为sliver组件提供子组件的`delegate`

SliverChildBuilderDelegate是Flutter中专门给“可滚动区域(Sliver)”使用的懒构建代理(lazy builder delegate)。它最常见的搭档是ListView.customGridView.customSliverListSliverFixedExtentList等需要按需构建子项的组件。

示例

  1. 无限列表
CustomScrollView(
  slivers: [
    SliverList(
      delegate: SliverChildBuilderDelegate(
        (context, index) => ListTile(title: Text('Item $index')),
        // childCount 不传 -> 无限列表
      )
    )
  ]
)
  1. 有限列表 + 空视图
SliverList(
  delegate: SliverChildBuilderDelegate(
    (context, index) => _buildRow(index),
    childCount: _items.length, //当_items.length为0时,builder不会被调用,列表为空
  )
)

与ListView.builder的关系

ListView.builder内部其实就是:

ListView.custom(
  childrenDelegate: SliverChildBuilderDelegate(...)
)

因此:

  • 如果只想做一个简单的可滚动列表 -> 直接用ListView.builder更简洁。
  • 如果需要与Sliver家族混排(例如AppBar、吸顶Tab、交错网格等) -> 用SliverChildBuilderDelegate + SliverList/SliverGrid

总结

凡是带Sliver的列表/网格,想懒加载就用SliverChildBuilderDelegate

构造函数

SliverChildBuilderDelegate.new(
  NullableIndexedWidgetBuilder builder, 
  {
    ChildIndexGetter? findChildIndexCallback, 
    int? childCount, 
    bool addAutomaticKeepAlives = true, 
    bool addRepaintBoundaries = true, 
    bool addSemanticIndexes = true, 
    SemanticIndexCallback semanticIndexCallback = _kDefaultSemanticIndexCallback, 
    int semanticIndexOffset = 0
  }
)

属性

参数类型作用一句话常见取值
builderWidget? Function(BuildContext, int)按需创建子 Widget返回 ListTileCard
childCountint?告诉框架“我一共有多少个孩子”,决定滚动条长度、是否还能继续滑列表长度;无限列表可省略
addAutomaticKeepAlivesbool是否给子项自动包一层 AutomaticKeepAliveClientMixin,让状态(如 TextField 内容)在滑出可视区后仍保留默认 true;如果子项无状态可设 false 省内存
addRepaintBoundariesbool是否给子项自动包一层 RepaintBoundary,减少重绘范围默认 true;极端性能优化时才关
estimatedChildCountint?给框架一个"预估"子项数量它不会限制builder的调用次数,也不会影响实际渲染,只是告诉框架一个大概值,当子项数量未知或很大,但又想滚动条不至于"忽大忽小"
findChildIndexCallbackChildIndexGetter?反向查找某个Key对应的子项索引当滚动位置恢复或跳转时,框架需要知道“当前屏幕上那个Key的Widget是第几个元素”,才能正确地把滚动偏移量映射到列表索引