flutter中ListView.builder的源码分析

ListView.builder是Flutter中常用的控件之一,用于构建具有大量数据的列表视图。下面是ListView.builder的源码分析:

  1. 构造函数

ListView.builder的构造函数如下:

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

其中,参数说明如下:

  • key:控件的唯一标识符。
  • scrollDirection:滚动方向,默认为垂直方向。
  • reverse:是否反向滚动,默认为false。
  • controller:滚动控制器。
  • primary:是否使用主轴上的滚动控制器,默认为null。
  • physics:滚动物理特性。
  • padding:内边距。
  • itemBuilder:列表项构建函数,用于创建具体的列表项控件。
  • itemCount:列表项数量。
  • addAutomaticKeepAlives:是否自动保留列表项状态,默认为true。
  • addRepaintBoundaries:是否添加重绘边界,默认为true。
  • addSemanticIndexes:是否添加语义索引,默认为true。
  • cacheExtent:缓存区域范围。
  • semanticChildCount:语义子项数量。
  • dragStartBehavior:拖动开始行为。
  1. build方法

ListView.builder的build方法如下:

@override
Widget build(BuildContext context) {
  final ScrollController scrollController = widget.controller ?? _defaultController;
  return ListView.custom(
    key: widget.key,
    scrollDirection: widget.scrollDirection,
    reverse: widget.reverse,
    controller: scrollController,
    primary: widget.primary,
    physics: widget.physics,
    padding: widget.padding,
    itemExtent: null,
    childrenDelegate: SliverChildBuilderDelegate(
      widget.itemBuilder,
      childCount: widget.itemCount,
      addAutomaticKeepAlives: widget.addAutomaticKeepAlives,
      addRepaintBoundaries: widget.addRepaintBoundaries,
      addSemanticIndexes: widget.addSemanticIndexes,
      semanticIndexCallback: widget.semanticIndexCallback,
      semanticDividerCallback: widget.semanticDividerCallback,
    ),
  );
}

在build方法中,ListView.builder实际上是使用了ListView.custom来构建列表视图。这里的参数与ListView.builder的参数基本一致,其中:

  • key:控件的唯一标识符。
  • scrollDirection:滚动方向,默认为垂直方向。
  • reverse:是否反向滚动,默认为false。
  • controller:滚动控制器。
  • primary:是否使用主轴上的滚动控制器,默认为null。
  • physics:滚动物理特性。
  • padding:内边距。
  • itemExtent:列表项的固定高度,这里为null。
  • childrenDelegate:子项代理,用于创建具体的列表项控件。
  1. SliverChildBuilderDelegate

在ListView.custom中,使用了SliverChildBuilderDelegate作为子项代理。SliverChildBuilderDelegate是一个抽象类,实现了SliverChildDelegate接口,用于创建具体的列表项控件。

SliverChildBuilderDelegate的构造函数如下:

SliverChildBuilderDelegate(
  this.builder, {
  this.childCount,
  this.addAutomaticKeepAlives = true,
  this.addRepaintBoundaries = true,
  this.addSemanticIndexes = true,
  this.semanticIndexCallback,
  this.semanticDividerCallback,
}) : assert(builder != null);

其中,参数说明如下:

  • builder:列表项构建函数,用于创建具体的列表项控件。
  • childCount:列表项数量。
  • addAutomaticKeepAlives:是否自动保留列表项状态,默认为true。
  • addRepaintBoundaries:是否添加重绘边界,默认为true。
  • addSemanticIndexes:是否添加语义索引,默认为true。
  • semanticIndexCallback:语义索引回调函数。
  • semanticDividerCallback:语义分隔符回调函数。

在SliverChildBuilderDelegate中,会根据builder函数和childCount参数创建具体的列表项控件。

总之,ListView.builder是Flutter中常用的控件之一,通过ListView.custom和SliverChildBuilderDelegate来创建具有大量数据的列表视图。

  1. ListView.custom

ListView.custom是Flutter中的一个控件,它继承自ScrollView,用于创建具有大量数据的滚动视图。ListView.custom的构造函数如下:

ListView.custom({
  Key key,
  Axis scrollDirection = Axis.vertical,
  bool reverse = false,
  ScrollController controller,
  bool primary,
  ScrollPhysics physics,
  EdgeInsetsGeometry padding,
  double itemExtent,
  bool shrinkWrap = false,
  Key center,
  double cacheExtent,
  int semanticChildCount,
  DragStartBehavior dragStartBehavior = DragStartBehavior.start,
  @required this.childrenDelegate,
}) : assert(childrenDelegate != null),
     super(key: key, scrollDirection: scrollDirection, reverse: reverse, controller: controller, primary: primary, physics: physics, padding: padding, cacheExtent: cacheExtent, semanticChildCount: semanticChildCount, dragStartBehavior: dragStartBehavior) {
    this.center = center;
    this.itemExtent = itemExtent;
    this.shrinkWrap = shrinkWrap;
}

其中,参数说明如下:

  • key:控件的唯一标识符。
  • scrollDirection:滚动方向,默认为垂直方向。
  • reverse:是否反向滚动,默认为false。
  • controller:滚动控制器。
  • primary:是否使用主轴上的滚动控制器,默认为null。
  • physics:滚动物理特性。
  • padding:内边距。
  • itemExtent:列表项的固定高度。
  • shrinkWrap:是否根据子项包裹内容,默认为false。
  • center:控件的中心点。
  • cacheExtent:缓存区域范围。
  • semanticChildCount:语义子项数量。
  • dragStartBehavior:拖动开始行为。
  • childrenDelegate:子项代理,用于创建具体的列表项控件。
  1. SliverChildBuilderDelegate

在ListView.custom中,使用了SliverChildBuilderDelegate作为子项代理。SliverChildBuilderDelegate是一个抽象类,实现了SliverChildDelegate接口,用于创建具体的列表项控件。

SliverChildBuilderDelegate的构造函数如下:

SliverChildBuilderDelegate(
  this.builder, {
  this.childCount,
  this.addAutomaticKeepAlives = true,
  this.addRepaintBoundaries = true,
  this.addSemanticIndexes = true,
  this.semanticIndexCallback,
  this.semanticDividerCallback,
}) : assert(builder != null);

其中,参数说明如下:

  • builder:列表项构建函数,用于创建具体的列表项控件。
  • childCount:列表项数量。
  • addAutomaticKeepAlives:是否自动保留列表项状态,默认为true。
  • addRepaintBoundaries:是否添加重绘边界,默认为true。
  • addSemanticIndexes:是否添加语义索引,默认为true。
  • semanticIndexCallback:语义索引回调函数。
  • semanticDividerCallback:语义分隔符回调函数。

在SliverChildBuilderDelegate中,会根据builder函数和childCount参数创建具体的列表项控件。

  1. build方法

ListView.custom的build方法如下:

@override
Widget build(BuildContext context) {
  final AxisDirection axisDirection = 
  getAxisDirectionFromAxisReverseAndDirectionality(context, widget.scrollDirection, widget.reverse);
  final ViewportOffset offset = widget.controller?.viewportDimensions == null ? null : widget.controller.position;
  return ShScrollbar(
  key: _scrollbarKey,
  controller: widget.controller, 
  isAlwaysShown: widget.scrollbarAlwaysShown, 
  child: ShrinkWrappingViewport( 
  axisDirection: axisDirection, offset: offset, slivers: <Widget>[ 
  SliverPadding( padding: widget.padding, sliver: SliverList( delegate: widget.childrenDelegate, ), ), ], ), ); }

在build方法中,使用了Scrollbar和ShrinkWrappingViewport来创建滚动视图。其中,Scrollbar用于添加滚动条,ShrinkWrappingViewport用于自适应子项大小的滚动视图。具体来说,ShrinkWrappingViewport会根据子项尺寸自动调整自身大小,从而避免不必要的滚动。SliverPadding和SliverList则用于添加内边距和列表项。

总之,ListView.custom和SliverChildBuilderDelegate是Flutter中用于创建具有大量数据的滚动视图的重要控件和类。在使用ListView.custom时,需要注意控件的参数设置和性能优化,以提高应用程序的性能和用户体验。

  1. 性能优化

在使用ListView.builder时,需要注意控件的性能优化,以避免出现卡顿和性能问题。以下是一些常用的性能优化技巧:

  • 尽量减少控件的渲染次数,可以使用AutomaticKeepAlive或KeepAliveNotifier等控件来避免重复渲染。
  • 尽量减小控件的尺寸和复杂度,可以使用简单的控件和布局方式来提高性能。
  • 尽量减少控件的嵌套层数,可以使用FlattenedWidget等控件来减少嵌套层数。
  • 尽量避免使用过多的动画和过渡效果,可以使用AnimatedSwitcher等控件来实现平滑的过渡效果。
  • 尽量避免在列表项中使用复杂的计算和操作,可以使用异步加载和缓存等技术来提高性能。
  • 尽量减小列表项的尺寸,可以使用ListView.separated等控件来添加分割线,减小列表项的高度。
  • 尽量避免在列表项中使用过多的图片和视频等资源,可以使用懒加载和缓存等技术来优化性能。

为了提高ListView.builder的性能和用户体验,需要开发者们根据具体应用场景,选择合适的性能优化技巧,从而避免出现卡顿和性能问题,提高应用程序的质量和稳定性。

猜你喜欢

转载自blog.csdn.net/qq_28563283/article/details/130349452