ListView.builder是Flutter中常用的控件之一,用于构建具有大量数据的列表视图。下面是ListView.builder的源码分析:
- 构造函数
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:拖动开始行为。
- 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:子项代理,用于创建具体的列表项控件。
- 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来创建具有大量数据的列表视图。
- 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:子项代理,用于创建具体的列表项控件。
- 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参数创建具体的列表项控件。
- 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时,需要注意控件的参数设置和性能优化,以提高应用程序的性能和用户体验。
- 性能优化
在使用ListView.builder时,需要注意控件的性能优化,以避免出现卡顿和性能问题。以下是一些常用的性能优化技巧:
- 尽量减少控件的渲染次数,可以使用AutomaticKeepAlive或KeepAliveNotifier等控件来避免重复渲染。
- 尽量减小控件的尺寸和复杂度,可以使用简单的控件和布局方式来提高性能。
- 尽量减少控件的嵌套层数,可以使用FlattenedWidget等控件来减少嵌套层数。
- 尽量避免使用过多的动画和过渡效果,可以使用AnimatedSwitcher等控件来实现平滑的过渡效果。
- 尽量避免在列表项中使用复杂的计算和操作,可以使用异步加载和缓存等技术来提高性能。
- 尽量减小列表项的尺寸,可以使用ListView.separated等控件来添加分割线,减小列表项的高度。
- 尽量避免在列表项中使用过多的图片和视频等资源,可以使用懒加载和缓存等技术来优化性能。
为了提高ListView.builder的性能和用户体验,需要开发者们根据具体应用场景,选择合适的性能优化技巧,从而避免出现卡顿和性能问题,提高应用程序的质量和稳定性。