Flutter.源码剖析 GridView flutter/packages/flutter/lib/src/widgets/scroll_view.dart/GridView
李俊才 的个人博客:blog.csdn.net/qq_28550263
本文地址:blog.csdn.net/qq_28550263…
本文供给 Flutter 框架中 GridView 类源码注释的中文翻译以及必要的剖析说明。
目 录
- 1. 类注释部分
- 2. 默许结构函数部分
- 3. GridView.builder结构函数部分
- 4. GridView.custom 结构函数部分
- 5. GridView.count 结构函数部分
- 6. GridView.extent结构函数部分
- 7. gridDelegate特点
- 8. childrenDelegate特点
- 9. buildChildLayout办法
1. 类注释部分
/// 一个可翻滚的二维组件数组。
///
/// {@youtube 560 315 https://www.youtube.com/watch?v=bLOtZDTm4H8}
///
/// 网格的主轴方向是其翻滚的方向([scrollDirection])。
///
/// 最常用的网格布局是 [GridView.count],它创立一个在穿插轴上有固定数量的瓷砖的布局,和
/// [GridView.extent],它创立一个瓷砖具有最大穿插轴规模的布局。自界说的 [SliverGridDelegate] 能够产生任意的2D
/// 子组件布局,包括不对齐或堆叠的布局。
///
/// 要创立一个具有很多(或无限)子组件的网格,运用 [GridView.builder] 结构函数,配合
/// [SliverGridDelegateWithFixedCrossAxisCount] 或 [SliverGridDelegateWithMaxCrossAxisExtent]
/// 作为 [gridDelegate]。
///
/// 要运用自界说的 [SliverChildDelegate],运用 [GridView.custom]。
///
/// 要创立一个线性的子组件数组,运用 [ListView]。
///
/// 要操控翻滚视图的初始翻滚偏移,供给一个设置了 [ScrollController.initialScrollOffset] 特点的 [controller]。
///
/// ## 转换到 [CustomScrollView]
///
/// [GridView] 基本上是一个在其 [CustomScrollView.slivers] 特点中有一个 [SliverGrid] 的 [CustomScrollView]。
///
/// 假如 [GridView] 不再足够,例如由于翻滚视图要同时有一个网格和一个列表,或许由于网格要与 [SliverAppBar] 结合等,
/// 那么从运用 [GridView] 到直接运用 [CustomScrollView] 的代码移植是直接的。
///
/// [GridView] 上的 [key],[scrollDirection],[reverse],[controller],[primary],[physics],
/// 和 [shrinkWrap] 特点直接映射到 [CustomScrollView] 上同名的特点。
///
/// [CustomScrollView.slivers] 特点应该是一个只包含 [SliverGrid] 的列表。
///
/// [GridView] 上的 [childrenDelegate] 特点对应于 [SliverGrid.delegate] 特点,
/// 而 [GridView] 上的 [gridDelegate] 特点对应于 [SliverGrid.gridDelegate] 特点。
///
/// [GridView],[GridView.count] 和 [GridView.extent]
/// 结构函数的 `children` 参数对应于 [childrenDelegate] 是一个具有相同参数的 [SliverChildListDelegate]。
/// [GridView.builder] 结构函数的 `itemBuilder` 和 `childCount` 参数对应于 [childrenDelegate] 是一个具有匹配参数的 [SliverChildBuilderDelegate]。
///
/// [GridView.count] 和 [GridView.extent] 结构函数创立
/// 自界说网格托付,并在 [SliverGrid] 上有同名的结构函数以便于转换:分别是 [SliverGrid.count] 和
/// [SliverGrid.extent]。
///
/// [padding] 特点对应于在 [CustomScrollView.slivers] 特点中有一个 [SliverPadding] 而不是网格本身,
/// 并且 [SliverGrid] 是 [SliverPadding] 的子组件。
///
/// 一旦代码被移植为运用 [CustomScrollView],其他的 slivers,如 [SliverList] 或 [SliverAppBar],
/// 能够放在 [CustomScrollView.slivers] 列表中。
///
/// {@tool snippet}
/// 这个示例演示了怎么创立一个有两列的 [GridView]。子组件之间的距离运用 `crossAxisSpacing` 和 `mainAxisSpacing` 特点设置。
///
/// ![GridView 显现了两列的六个具有不同背景色彩的子组件](https://flutter.github.io/assets-for-api-docs/assets/widgets/grid_view.png)
///
/// ```dart
/// GridView.count(
/// primary: false,
/// padding: const EdgeInsets.all(20),
/// crossAxisSpacing: 10,
/// mainAxisSpacing: 10,
/// crossAxisCount: 2,
/// children: <Widget>[
/// Container(
/// padding: const EdgeInsets.all(8),
/// color: Colors.teal[100],
/// child: const Text("He'd have you all unravel at the"),
/// ),
/// Container(
/// padding: const EdgeInsets.all(8),
/// color: Colors.teal[200],
/// child: const Text('Heed not the rabble'),
/// ),
/// Container(
/// padding: const EdgeInsets.all(8),
/// color: Colors.teal[300],
/// child: const Text('Sound of screams but the'),
/// ),
/// Container(
/// padding: const EdgeInsets.all(8),
/// color: Colors.teal[400],
/// child: const Text('Who scream'),
/// ),
/// Container(
/// padding: const EdgeInsets.all(8),
/// color: Colors.teal[500],
/// child: const Text('Revolution is coming...'),
/// ),
/// Container(
/// padding: const EdgeInsets.all(8),
/// color: Colors.teal[600],
/// child: const Text('Revolution, they...'),
/// ),
/// ],
/// )
/// ```
/// {@end-tool}
///
/// {@tool snippet}
/// 这个示例展现了怎么运用 [CustomScrollView] 和 [SliverGrid] 创立与上一个示例相同的网格。
///
/// ![CustomScrollView 包含一个 SliverGrid,它显现了两列的六个具有不同背景色彩的子组件](https://www.6hu.cc/storage/2023/11/220210-Om31Dr.png)
///
/// ```dart
/// CustomScrollView(
/// primary: false,
/// slivers: <Widget>[
/// SliverPadding(
/// padding: const EdgeInsets.all(20),
/// sliver: SliverGrid.count(
/// crossAxisSpacing: 10,
/// mainAxisSpacing: 10,
/// crossAxisCount: 2,
/// children: <Widget>[
/// Container(
/// padding: const EdgeInsets.all(8),
/// color: Colors.green[100],
/// child: const Text("He'd have you all unravel at the"),
/// ),
/// Container(
/// padding: const EdgeInsets.all(8),
/// color: Colors.green[200],
/// child: const Text('Heed not the rabble'),
/// ),
/// Container(
/// padding: const EdgeInsets.all(8),
/// color: Colors.green[300],
/// child: const Text('Sound of screams but the'),
/// ),
/// Container(
/// padding: const EdgeInsets.all(8),
/// color: Colors.green[400],
/// child: const Text('Who scream'),
/// ),
/// Container(
/// padding: const EdgeInsets.all(8),
/// color: Colors.green[500],
/// child: const Text('Revolution is coming...'),
/// ),
/// Container(
/// padding: const EdgeInsets.all(8),
/// color: Colors.green[600],
/// child: const Text('Revolution, they...'),
/// ),
/// ],
/// ),
/// ),
/// ],
/// )
/// ```
/// {@end-tool}
///
/// 默许情况下,[GridView] 会主动填充网格的翻滚鸿沟的约束,以避免 [MediaQuery] 的填充指示的部分遮挡。
/// 要避免这种行为,用零 [padding] 特点覆盖。
///
/// {@tool snippet}
/// 下面的示例演示了怎么运用 [MediaQuery.removePadding] 覆盖默许的顶部填充。
///
/// ```dart
/// Widget myWidget(BuildContext context) {
/// return MediaQuery.removePadding(
/// context: context,
/// removeTop: true,
/// child: GridView.builder(
/// gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
/// crossAxisCount: 3,
/// ),
/// itemCount: 300,
/// itemBuilder: (BuildContext context, int index) {
/// return Card(
/// color: Colors.amber,
/// child: Center(child: Text('$index')),
/// );
/// }
/// ),
/// );
/// }
/// ```
/// {@end-tool}
///
/// {@tool dartpad}
/// 这个示例展现了在 [GridView] 或 [ListView] 中 [ListTile] 挑选的自界说完成。
/// 长按任何 ListTile 以启用挑选模式。
///
/// ** 查看 examples/api/lib/widgets/scroll_view/list_view.0.dart 中的代码 **
/// {@end-tool}
///
/// 另请参看:
///
/// * [SingleChildScrollView],这是一个有一个单一子组件的可翻滚组件。
/// * [ListView],这是一个可翻滚的,线性的组件列表。
/// * [PageView],这是一个翻滚的子组件列表,每个子组件都是视口的巨细。
/// * [CustomScrollView],这是一个创立自界说翻滚效果的可翻滚组件。
/// * [SliverGridDelegateWithFixedCrossAxisCount],它创立一个在穿插轴上有固定数量的瓷砖的布局。
/// * [SliverGridDelegateWithMaxCrossAxisExtent],它创立一个瓷砖具有最大穿插轴规模的布局。
/// * [ScrollNotification] 和 [NotificationListener],它们能够用来观察翻滚方位,而无需运用 [ScrollController]。
/// * [布局组件目录](https://flutter.dev/widgets/layout/)。
class GridView extends BoxScrollView {
// ...
}
2. 默许结构函数部分
/// 运用自界说 [SliverGridDelegate] 创立一个可翻滚的二维组件数组。
///
/// [gridDelegate] 参数不能为空。
///
/// `addAutomaticKeepAlives` 参数对应于 [SliverChildListDelegate.addAutomaticKeepAlives] 特点。
/// `addRepaintBoundaries` 参数对应于 [SliverChildListDelegate.addRepaintBoundaries] 特点。两者都不能为 null。
GridView({
super.key,
super.scrollDirection,
super.reverse,
super.controller,
super.primary,
super.physics,
super.shrinkWrap,
super.padding,
required this.gridDelegate,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
super.cacheExtent,
List<Widget> children = const <Widget>[],
int? semanticChildCount,
super.dragStartBehavior,
super.clipBehavior,
super.keyboardDismissBehavior,
super.restorationId,
}) : childrenDelegate = SliverChildListDelegate(
children,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries,
addSemanticIndexes: addSemanticIndexes,
),
super(
semanticChildCount: semanticChildCount ?? children.length,
);
从 GridView 默许结构函数的结构能够看出,它本质上不过是创立了一个SliverChildListDelegate目标并赋值给childrenDelegate
。
而SliverChildListDelegate是SliverChildDelegate的一个完成,它运用一个固定的子部件列表来生成网格的子部件。这儿,children
参数便是这个列表。另外,addAutomaticKeepAlives
、addRepaintBoundaries
和addSemanticIndexes
参数用于操控子部件的生命周期、是否添加重绘鸿沟和语义索引。
另外一方面,该结构函数种调用了其父类(BoxScrollView)的结构函数。semanticChildCount
参数用于语义剖析,它表示GridView中的子部件数量。假如semanticChildCount
为null
,则运用children.length
作为默许值。
3. GridView.builder结构函数部分
GridView.builder结构函数用于创立一个能够翻滚的,按需创立的二维部件数组。这关于具有很多(或无限)子部件的网格视图十分适宜,由于构建器只会为实际可见的子部件调用。
/// 创立一个可翻滚的,按需创立的二维部件数组。
///
/// 关于具有很多(或无限)子部件的网格视图,此结构函数是适宜的,由于构建器只会为实际可见的子部件调用。
///
/// 供给非空的 `itemCount` 能够进步 [GridView] 估计最大翻滚规模的能力。
///
/// `itemBuilder` 只会被调用大于等于零且小于 `itemCount` 的索引。
///
/// {@macro flutter.widgets.ListView.builder.itemBuilder}
///
/// {@macro flutter.widgets.PageView.findChildIndexCallback}
///
/// [gridDelegate] 参数是必需的。
///
/// `addAutomaticKeepAlives` 参数对应于 [SliverChildBuilderDelegate.addAutomaticKeepAlives] 特点。
/// `addRepaintBoundaries` 参数对应于 [SliverChildBuilderDelegate.addRepaintBoundaries] 特点。
/// `addSemanticIndexes` 参数对应于 [SliverChildBuilderDelegate.addSemanticIndexes] 特点。
GridView.builder({
super.key,
super.scrollDirection,
super.reverse,
super.controller,
super.primary,
super.physics,
super.shrinkWrap,
super.padding,
required this.gridDelegate,
required NullableIndexedWidgetBuilder itemBuilder,
ChildIndexGetter? findChildIndexCallback,
int? itemCount,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
super.cacheExtent,
int? semanticChildCount,
super.dragStartBehavior,
super.keyboardDismissBehavior,
super.restorationId,
super.clipBehavior,
}) : childrenDelegate = SliverChildBuilderDelegate(
itemBuilder,
findChildIndexCallback: findChildIndexCallback,
childCount: itemCount,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries,
addSemanticIndexes: addSemanticIndexes,
),
super(
semanticChildCount: semanticChildCount ?? itemCount,
);
从代码能够看到,这个结构函数接纳多个参数,其间最重要的两个参数是gridDelegate
和itemBuilder
。
-
gridDelegate
是一个SliverGridDelegate目标,它决议了网格的布局。这是一个必需的参数。 -
itemBuilder
是一个函数,它接纳一个 BuildContext 和一个索引,然后回来一个 Widget。这个函数只会被调用大于等于零且小于itemCount
的索引。这是一个必需的参数。
GridView.builder结构函数的作业原理是,当需求烘托一个子部件时,它会调用itemBuilder
函数,传入当前的BuildContext和子部件的索引,然后将回来的 组件 添加到网格中。这样,只有当子部件实际需求显现时,才会调用itemBuilder
函数创立子部件。
此外,GridView.builder还接纳一些其他参数,如itemCount
、addAutomaticKeepAlives
、addRepaintBoundaries
和addSemanticIndexes
,这些参数用于操控GridView的行为。
最终,GridView.builder通过SliverChildBuilderDelegate创立了一个childrenDelegate
,然后传递给GridView的父类结构函数。这个childrenDelegate
决议了怎么为GridView创立子部件。
4. GridView.custom 结构函数部分
/// 运用自界说 [SliverGridDelegate] 和自界说 [SliverChildDelegate] 创立一个可翻滚的二维部件数组。
///
/// 要运用 [IndexedWidgetBuilder] 回调来构建子部件,能够运用 [SliverChildBuilderDelegate] 或运用 [GridView.builder] 结构函数。
///
/// [gridDelegate] 和 [childrenDelegate] 参数不能为空。
const GridView.custom({
super.key,
super.scrollDirection,
super.reverse,
super.controller,
super.primary,
super.physics,
super.shrinkWrap,
super.padding,
required this.gridDelegate,
required this.childrenDelegate,
super.cacheExtent,
super.semanticChildCount,
super.dragStartBehavior,
super.keyboardDismissBehavior,
super.restorationId,
super.clipBehavior,
});
GridView.custom结构函数用于创立一个可翻滚的二维部件数组,它答应你彻底自界说 **SliverGridDelegate **和SliverChildDelegate。
- SliverGridDelegate决议了网格的布局,例如每行的列数、每个子部件的尺寸等。
- SliverChildDelegate决议了怎么生成网格的子部件。你能够运用SliverChildBuilderDelegate来按需生成子部件,或许运用 SliverChildListDelegate 来生成一个固定列表的子部件。
GridView.custom结构函数接纳多个参数,其间最重要的两个参数是 gridDelegate 和 childrenDelegate,这两个参数都是必需的。
-
gridDelegate
是一个SliverGridDelegate目标,它决议了网格的布局。 -
childrenDelegate
是一个SliverChildDelegate目标,它决议了怎么为 GridView 创立子部件。
GridView.custom会依据
gridDelegate
的设置来布局网格,然后调用childrenDelegate
来生成子部件。这样,你能够彻底自界说GridView的布局和子部件的生成方式。
在这个结构函数的完成种:
-
gridDelegate
完成网格的布局作业:gridDelegate
是SliverGridDelegate类型的目标,它是一个托付,担任界说网格的布局。具体来说,它决议了网格中每行的列数,以及每个格子的巨细。当GridView需求布局其子部件时,它会调用gridDelegate
的办法来获取布局信息。所以,你能够说 gridDelegate 托付了网格的布局作业。 -
childrenDelegate
完成子部件的创立作业:childrenDelegate
是SliverChildDelegate类型的目标,它是一个托付,担任创立网格的子部件。具体来说,当GridView需求烘托一个新的子部件时,它会调用childrenDelegate
的办法来创立这个子部件。
5. GridView.count 结构函数部分
GridView.count 结构函数用于创立一个可翻滚的二维部件数组,其间穿插轴上有固定数量的格子。这个结构函数接纳多个参数,其间最重要的是
crossAxisCount
,它决议了穿插轴上的格子数量。此外,还能够设置 mainAxisSpacing 和 crossAxisSpacing 来操控格子之间的距离,以及 childAspectRatio 来操控每个格子的宽高比。
该结构函数的代码为:
/// 创立一个可翻滚的,二维部件数组,穿插轴上有固定数量的格子。
///
/// 运用 [SliverGridDelegateWithFixedCrossAxisCount] 作为 [gridDelegate]。
///
/// `addAutomaticKeepAlives` 参数对应于 [SliverChildListDelegate.addAutomaticKeepAlives] 特点。
/// `addRepaintBoundaries` 参数对应于 [SliverChildListDelegate.addRepaintBoundaries] 特点。两者都不能为空。
///
/// 另请参看:
///
/// * [SliverGrid.count],[SliverGrid] 的等效结构函数。
GridView.count({
super.key,
super.scrollDirection,
super.reverse,
super.controller,
super.primary,
super.physics,
super.shrinkWrap,
super.padding,
required int crossAxisCount,
double mainAxisSpacing = 0.0,
double crossAxisSpacing = 0.0,
double childAspectRatio = 1.0,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
super.cacheExtent,
List<Widget> children = const <Widget>[],
int? semanticChildCount,
super.dragStartBehavior,
super.keyboardDismissBehavior,
super.restorationId,
super.clipBehavior,
}) : gridDelegate = SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: crossAxisCount,
mainAxisSpacing: mainAxisSpacing,
crossAxisSpacing: crossAxisSpacing,
childAspectRatio: childAspectRatio,
),
childrenDelegate = SliverChildListDelegate(
children,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries,
addSemanticIndexes: addSemanticIndexes,
),
super(
semanticChildCount: semanticChildCount ?? children.length,
);
从代码能够看出,GridView.count结构函数会依据crossAxisCount
、mainAxisSpacing
、crossAxisSpacing
和childAspectRatio
的值来布局网格,然后依据children
列表来创立子部件。这使得你能够轻松地创立一个具有固定列数的网格视图。
在GridView.count结构函数中,gridDelegate
被设置为SliverGridDelegateWithFixedCrossAxisCount目标。这个目标会依据crossAxisCount
、mainAxisSpacing
、crossAxisSpacing
和childAspectRatio
的值来布局网格。
childrenDelegate
被设置为SliverChildListDelegate目标,它会依据传入的children
列表来创立子部件。addAutomaticKeepAlives
、addRepaintBoundaries
和addSemanticIndexes
参数会传递给SliverChildListDelegate,用于操控子部件的生命周期、是否添加重绘鸿沟和语义索引。
6. GridView.extent结构函数部分
GridView.extent 结构函数用于创立一个可翻滚的二维部件数组,其间穿插轴上的每个格子都有最大的宽度。
这个结构函数接纳多个参数,其间最重要的是 maxCrossAxisExtent,它决议了穿插轴上每个格子的最大宽度。此外,还能够设置 mainAxisSpacing 和 crossAxisSpacing 来操控格子之间的距离,以及 childAspectRatio 来操控每个格子的宽高比。
该结构函数源码为:
/// 创立一个可翻滚的,二维部件数组,每个格子在穿插轴上都有最大的规模。
///
/// 运用 [SliverGridDelegateWithMaxCrossAxisExtent] 作为 [gridDelegate]。
///
/// `addAutomaticKeepAlives` 参数对应于 [SliverChildListDelegate.addAutomaticKeepAlives] 特点。
/// `addRepaintBoundaries` 参数对应于 [SliverChildListDelegate.addRepaintBoundaries] 特点。两者都不能为空。
///
/// 另请参看:
///
/// * [SliverGrid.extent],[SliverGrid] 的等效结构函数。
GridView.extent({
super.key,
super.scrollDirection,
super.reverse,
super.controller,
super.primary,
super.physics,
super.shrinkWrap,
super.padding,
required double maxCrossAxisExtent,
double mainAxisSpacing = 0.0,
double crossAxisSpacing = 0.0,
double childAspectRatio = 1.0,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
super.cacheExtent,
List<Widget> children = const <Widget>[],
int? semanticChildCount,
super.dragStartBehavior,
super.keyboardDismissBehavior,
super.restorationId,
super.clipBehavior,
}) : gridDelegate = SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: maxCrossAxisExtent,
mainAxisSpacing: mainAxisSpacing,
crossAxisSpacing: crossAxisSpacing,
childAspectRatio: childAspectRatio,
),
childrenDelegate = SliverChildListDelegate(
children,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries,
addSemanticIndexes: addSemanticIndexes,
),
super(
semanticChildCount: semanticChildCount ?? children.length,
);
GridView.extent结构函数会依据maxCrossAxisExtent
、mainAxisSpacing
、crossAxisSpacing
和childAspectRatio
的值来布局网格,然后依据children
列表来创立子部件。这使得你能够轻松地创立一个具有固定最大宽度的网格视图。
在GridView.extent结构函数中,gridDelegate
被设置为SliverGridDelegateWithMaxCrossAxisExtent目标。这个目标会依据maxCrossAxisExtent
、mainAxisSpacing
、crossAxisSpacing
和childAspectRatio
的值来布局网格。
childrenDelegate
被设置为SliverChildListDelegate目标,它会依据传入的children
列表来创立子部件。addAutomaticKeepAlives
、addRepaintBoundaries
和addSemanticIndexes
参数会传递给SliverChildListDelegate,用于操控子部件的生命周期、是否添加重绘鸿沟和语义索引。
7. gridDelegate特点
gridDelegate 是 GridView 类中的一个特点,它的类型是 SliverGridDelegate。这个特点是一个托付(delegate),它决议了 GridView 中子部件的布局。
其源代码为:
/// 一个托付,操控 [GridView] 中子部件的布局。
///
/// [GridView],[GridView.builder] 和 [GridView.custom] 结构函数答应你清晰指定这个托付。其他结构函数隐式创立一个 [gridDelegate]。
final SliverGridDelegate gridDelegate;
gridDelegate
特点的效果便是界说GridView中子部件的布局。这使得GridView能够灵敏地习惯各种需求,例如创立固定列数的网格,或许创立具有固定最大宽度的网格。
SliverGridDelegate是一个抽象类,它有两个常用的子类:SliverGridDelegateWithFixedCrossAxisCount和SliverGridDelegateWithMaxCrossAxisExtent。
- SliverGridDelegateWithFixedCrossAxisCount创立一个网格,其间穿插轴上有固定数量的格子。你能够指定穿插轴上的格子数量,以及格子之间的距离和宽高比。
- SliverGridDelegateWithMaxCrossAxisExtent创立一个网格,其间穿插轴上的每个格子都有最大的宽度。你能够指定每个格子的最大宽度,以及格子之间的距离和宽高比。
在GridView、GridView.builder和GridView.custom结构函数中,你能够清晰指定gridDelegate
。在其他结构函数中,gridDelegate
会主动创立。
8. childrenDelegate特点
/// 一个托付,为 [GridView] 供给子部件。
///
/// [GridView.custom] 结构函数答应你清晰指定这个托付。其他结构函数创立一个包装给定子部件列表的 [childrenDelegate]。
final SliverChildDelegate childrenDelegate;
能够看到,childrenDelegate
特点类型为SliverChildDelegate。这个特点是一个托付(delegate) ,它决议了怎么为GridView创立子部件。
SliverChildDelegate是一个抽象类,它有两个常用的子类:SliverChildListDelegate和SliverChildBuilderDelegate。其间:
- SliverChildListDelegate接纳一个固定长度的子部件列表,然后按照列表顺序创立子部件。
- SliverChildBuilderDelegate接纳一个构建函数,然后按需创立子部件。这关于具有大量子部件的 GridView 十分有用,由于只有当子部件实际需求显现时,才会调用构建函数创立子部件。
在GridView.custom结构函数中,你能够清晰指定childrenDelegate
。在其他结构函数中,childrenDelegate
会主动创立,通常是包装给定的子部件列表。
因此,childrenDelegate 特点的效果便是界说怎么为 GridView 创立子部件。这使得 GridView 能够灵敏地习惯各种需求,例如创立固定数量的子部件,或许按需创立子部件。
9. buildChildLayout办法
buildChildLayout 担任构建 GridView 的子布局。
@override
Widget buildChildLayout(BuildContext context) {
return SliverGrid(
delegate: childrenDelegate,
gridDelegate: gridDelegate,
);
}
buildChildLayout
办法的效果便是依据GridView的特点来创立一个SliverGrid目标,这个SliverGrid目标界说了GridView的子布局。
这个办法接纳一个BuildContext目标作为参数,然后回来一个 SliverGrid 目标。
SliverGrid是一个能够在网格中显现其子项的滑动列表。它需求两个参数:delegate
和gridDelegate
:
-
delegate
参数是一个SliverChildDelegate目标,它决议了怎么创立和布局子项。在GridView中,这个参数的值是childrenDelegate
特点。 -
gridDelegate
参数是一个SliverGridDelegate目标,它决议了网格的布局。在GridView中,这个参数的值是gridDelegate
特点。