Source code analysis of ListView.builder in flutter

ListView.builder is one of the commonly used controls in Flutter, which is used to build a list view with a large amount of data. The following is the source code analysis of ListView.builder:

  1. Constructor

The constructor of ListView.builder is as follows:

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,
})

Among them, the parameters are described as follows:

  • key: A unique identifier for the control.
  • scrollDirection: scrolling direction, the default is vertical direction.
  • reverse: Whether to scroll in reverse, the default is false.
  • controller: scroll controller.
  • primary: Whether to use the scroll controller on the main axis, the default is null.
  • physics: scroll physics.
  • padding: inner margin.
  • itemBuilder: List item builder function, used to create specific list item controls.
  • itemCount: the number of list items.
  • addAutomaticKeepAlives: Whether to automatically keep the state of the list item, the default is true.
  • addRepaintBoundaries: Whether to add repaint boundaries, the default is true.
  • addSemanticIndexes: Whether to add semantic indexes, the default is true.
  • cacheExtent: The extent of the cache area.
  • semanticChildCount: the number of semantic children.
  • dragStartBehavior: drag start behavior.
  1. build method

The build method of ListView.builder is as follows:

@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,
    ),
  );
}

In the build method, ListView.builder actually uses ListView.custom to build the list view. The parameters here are basically the same as those of ListView.builder, where:

  • key: A unique identifier for the control.
  • scrollDirection: scrolling direction, the default is vertical direction.
  • reverse: Whether to scroll in reverse, the default is false.
  • controller: scroll controller.
  • primary: Whether to use the scroll controller on the main axis, the default is null.
  • physics: scroll physics.
  • padding: inner margin.
  • itemExtent: The fixed height of the list item, here is null.
  • childrenDelegate: Child delegate, used to create specific list item controls.
  1. SliverChildBuilderDelegate

In ListView.custom, SliverChildBuilderDelegate is used as a sub-item proxy. SliverChildBuilderDelegate is an abstract class that implements the SliverChildDelegate interface and is used to create specific list item controls.

The constructor of SliverChildBuilderDelegate is as follows:

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

Among them, the parameters are described as follows:

  • builder: List item construction function, used to create a specific list item control.
  • childCount: The number of list items.
  • addAutomaticKeepAlives: Whether to automatically keep the state of the list item, the default is true.
  • addRepaintBoundaries: Whether to add repaint boundaries, the default is true.
  • addSemanticIndexes: Whether to add semantic indexes, the default is true.
  • semanticIndexCallback: semantic index callback function.
  • semanticDividerCallback: semantic divider callback function.

In SliverChildBuilderDelegate, a specific list item control will be created according to the builder function and the childCount parameter.

In short, ListView.builder is one of the commonly used controls in Flutter. ListView.custom and SliverChildBuilderDelegate are used to create a list view with a large amount of data.

  1. ListView.custom

ListView.custom is a control in Flutter that inherits from ScrollView and is used to create scroll views with large amounts of data. The constructor of ListView.custom is as follows:

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;
}

Among them, the parameters are described as follows:

  • key: A unique identifier for the control.
  • scrollDirection: scrolling direction, the default is vertical direction.
  • reverse: Whether to scroll in reverse, the default is false.
  • controller: scroll controller.
  • primary: Whether to use the scroll controller on the main axis, the default is null.
  • physics: scroll physics.
  • padding: inner margin.
  • itemExtent: The fixed height of the list item.
  • shrinkWrap: Whether to wrap the content according to the subitem, the default is false.
  • center: the center point of the control.
  • cacheExtent: The extent of the cache area.
  • semanticChildCount: the number of semantic children.
  • dragStartBehavior: drag start behavior.
  • childrenDelegate: Child delegate, used to create specific list item controls.
  1. SliverChildBuilderDelegate

In ListView.custom, SliverChildBuilderDelegate is used as a sub-item proxy. SliverChildBuilderDelegate is an abstract class that implements the SliverChildDelegate interface and is used to create specific list item controls.

The constructor of SliverChildBuilderDelegate is as follows:

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

Among them, the parameters are described as follows:

  • builder: List item construction function, used to create a specific list item control.
  • childCount: The number of list items.
  • addAutomaticKeepAlives: Whether to automatically keep the state of the list item, the default is true.
  • addRepaintBoundaries: Whether to add repaint boundaries, the default is true.
  • addSemanticIndexes: Whether to add semantic indexes, the default is true.
  • semanticIndexCallback: semantic index callback function.
  • semanticDividerCallback: semantic divider callback function.

In SliverChildBuilderDelegate, a specific list item control will be created according to the builder function and the childCount parameter.

  1. build method

The build method of ListView.custom is as follows:

@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, ), ), ], ), ); }

In the build method, Scrollbar and ShrinkWrappingViewport are used to create the scroll view. Among them, Scrollbar is used to add a scroll bar, and ShrinkWrappingViewport is used to adapt the scroll view of the size of the child. Specifically, ShrinkWrappingViewport will automatically adjust its size according to the size of its children, thus avoiding unnecessary scrolling. SliverPadding and SliverList are used to add padding and list items.

In summary, ListView.custom and SliverChildBuilderDelegate are important controls and classes in Flutter for creating scroll views with large amounts of data. When using ListView.custom, you need to pay attention to the parameter setting and performance optimization of the control to improve the performance and user experience of the application.

  1. performance optimization

When using ListView.builder, you need to pay attention to the performance optimization of the control to avoid lag and performance problems. Here are some common performance optimization techniques:

  • Minimize the rendering times of the control, you can use controls such as AutomaticKeepAlive or KeepAliveNotifier to avoid repeated rendering.
  • Minimize the size and complexity of controls, and use simple controls and layouts to improve performance.
  • Minimize the number of nested layers of controls, you can use controls such as FlattenedWidget to reduce the number of nested layers.
  • Try to avoid using too many animations and transition effects, you can use controls such as AnimatedSwitcher to achieve smooth transition effects.
  • Try to avoid using complex calculations and operations in list items, you can use techniques such as asynchronous loading and caching to improve performance.
  • To minimize the size of list items, you can use controls such as ListView.separated to add dividing lines to reduce the height of list items.
  • Try to avoid using too many resources such as pictures and videos in the list items, and you can use techniques such as lazy loading and caching to optimize performance.

In order to improve the performance and user experience of ListView.builder, developers need to choose appropriate performance optimization techniques according to specific application scenarios, so as to avoid freezes and performance problems, and improve the quality and stability of applications.

Guess you like

Origin blog.csdn.net/qq_28563283/article/details/130349452