|
3 | 3 | // found in the LICENSE file.
|
4 | 4 |
|
5 | 5 | import 'dart:collection' show HashMap, SplayTreeMap;
|
| 6 | +import 'dart:math' as math; |
6 | 7 |
|
7 | 8 | import 'package:flutter/foundation.dart';
|
8 | 9 | import 'package:flutter/rendering.dart';
|
@@ -1035,6 +1036,184 @@ class SliverList extends SliverMultiBoxAdaptorWidget {
|
1035 | 1036 | required super.delegate,
|
1036 | 1037 | });
|
1037 | 1038 |
|
| 1039 | + /// A sliver that places multiple box children in a linear array along the main |
| 1040 | + /// axis. |
| 1041 | + /// |
| 1042 | + /// This constructor is appropriate for sliver lists with a large (or |
| 1043 | + /// infinite) number of children because the builder is called only for those |
| 1044 | + /// children that are actually visible. |
| 1045 | + /// |
| 1046 | + /// Providing a non-null `itemCount` improves the ability of the [SliverGrid] |
| 1047 | + /// to estimate the maximum scroll extent. |
| 1048 | + /// |
| 1049 | + /// `itemBuilder` will be called only with indices greater than or equal to |
| 1050 | + /// zero and less than `itemCount`. |
| 1051 | + /// |
| 1052 | + /// {@macro flutter.widgets.ListView.builder.itemBuilder} |
| 1053 | + /// |
| 1054 | + /// {@macro flutter.widgets.PageView.findChildIndexCallback} |
| 1055 | + /// |
| 1056 | + /// The `addAutomaticKeepAlives` argument corresponds to the |
| 1057 | + /// [SliverChildBuilderDelegate.addAutomaticKeepAlives] property. The |
| 1058 | + /// `addRepaintBoundaries` argument corresponds to the |
| 1059 | + /// [SliverChildBuilderDelegate.addRepaintBoundaries] property. The |
| 1060 | + /// `addSemanticIndexes` argument corresponds to the |
| 1061 | + /// [SliverChildBuilderDelegate.addSemanticIndexes] property. |
| 1062 | + /// |
| 1063 | + /// {@tool snippet} |
| 1064 | + /// This example, which would be inserted into a [CustomScrollView.slivers] |
| 1065 | + /// list, shows an infinite number of items in varying shades of blue: |
| 1066 | + /// |
| 1067 | + /// ```dart |
| 1068 | + /// SliverList.builder( |
| 1069 | + /// itemBuilder: (BuildContext context, int index) { |
| 1070 | + /// return Container( |
| 1071 | + /// alignment: Alignment.center, |
| 1072 | + /// color: Colors.lightBlue[100 * (index % 9)], |
| 1073 | + /// child: Text('list item $index'), |
| 1074 | + /// ); |
| 1075 | + /// }, |
| 1076 | + /// ) |
| 1077 | + /// ``` |
| 1078 | + /// {@end-tool} |
| 1079 | + SliverList.builder({ |
| 1080 | + super.key, |
| 1081 | + required NullableIndexedWidgetBuilder itemBuilder, |
| 1082 | + ChildIndexGetter? findChildIndexCallback, |
| 1083 | + int? itemCount, |
| 1084 | + bool addAutomaticKeepAlives = true, |
| 1085 | + bool addRepaintBoundaries = true, |
| 1086 | + bool addSemanticIndexes = true, |
| 1087 | + }) : super(delegate: SliverChildBuilderDelegate( |
| 1088 | + itemBuilder, |
| 1089 | + findChildIndexCallback: findChildIndexCallback, |
| 1090 | + childCount: itemCount, |
| 1091 | + addAutomaticKeepAlives: addAutomaticKeepAlives, |
| 1092 | + addRepaintBoundaries: addRepaintBoundaries, |
| 1093 | + addSemanticIndexes: addSemanticIndexes, |
| 1094 | + )); |
| 1095 | + |
| 1096 | + /// A sliver that places multiple box children, separated by box widgets, in a linear array along the main |
| 1097 | + /// axis. |
| 1098 | + /// |
| 1099 | + /// This constructor is appropriate for sliver lists with a large (or |
| 1100 | + /// infinite) number of children because the builder is called only for those |
| 1101 | + /// children that are actually visible. |
| 1102 | + /// |
| 1103 | + /// Providing a non-null `itemCount` improves the ability of the [SliverGrid] |
| 1104 | + /// to estimate the maximum scroll extent. |
| 1105 | + /// |
| 1106 | + /// `itemBuilder` will be called only with indices greater than or equal to |
| 1107 | + /// zero and less than `itemCount`. |
| 1108 | + /// |
| 1109 | + /// {@macro flutter.widgets.ListView.builder.itemBuilder} |
| 1110 | + /// |
| 1111 | + /// {@macro flutter.widgets.PageView.findChildIndexCallback} |
| 1112 | + /// |
| 1113 | + /// |
| 1114 | + /// The `separatorBuilder` is similar to `itemBuilder`, except it is the widget |
| 1115 | + /// that gets placed between itemBuilder(context, index) and itemBuilder(context, index + 1). |
| 1116 | + /// |
| 1117 | + /// The `addAutomaticKeepAlives` argument corresponds to the |
| 1118 | + /// [SliverChildBuilderDelegate.addAutomaticKeepAlives] property. The |
| 1119 | + /// `addRepaintBoundaries` argument corresponds to the |
| 1120 | + /// [SliverChildBuilderDelegate.addRepaintBoundaries] property. The |
| 1121 | + /// `addSemanticIndexes` argument corresponds to the |
| 1122 | + /// [SliverChildBuilderDelegate.addSemanticIndexes] property. |
| 1123 | + /// {@tool snippet} |
| 1124 | + /// |
| 1125 | + /// This example shows how to create a [SliverList] whose [Container] items |
| 1126 | + /// are separated by [Divider]s. |
| 1127 | + /// |
| 1128 | + /// ```dart |
| 1129 | + /// SliverList.separated( |
| 1130 | + /// itemBuilder: (BuildContext context, int index) { |
| 1131 | + /// return Container( |
| 1132 | + /// alignment: Alignment.center, |
| 1133 | + /// color: Colors.lightBlue[100 * (index % 9)], |
| 1134 | + /// child: Text('list item $index'), |
| 1135 | + /// ); |
| 1136 | + /// }, |
| 1137 | + /// separatorBuilder: (BuildContext context, int index) => const Divider(), |
| 1138 | + /// ) |
| 1139 | + /// ``` |
| 1140 | + /// {@end-tool} |
| 1141 | + SliverList.separated({ |
| 1142 | + super.key, |
| 1143 | + required NullableIndexedWidgetBuilder itemBuilder, |
| 1144 | + ChildIndexGetter? findChildIndexCallback, |
| 1145 | + required NullableIndexedWidgetBuilder separatorBuilder, |
| 1146 | + int? itemCount, |
| 1147 | + bool addAutomaticKeepAlives = true, |
| 1148 | + bool addRepaintBoundaries = true, |
| 1149 | + bool addSemanticIndexes = true, |
| 1150 | + }) : assert(itemBuilder != null), |
| 1151 | + assert(separatorBuilder != null), |
| 1152 | + super(delegate: SliverChildBuilderDelegate( |
| 1153 | + (BuildContext context, int index) { |
| 1154 | + final int itemIndex = index ~/ 2; |
| 1155 | + final Widget? widget; |
| 1156 | + if (index.isEven) { |
| 1157 | + widget = itemBuilder(context, itemIndex); |
| 1158 | + } else { |
| 1159 | + widget = separatorBuilder(context, itemIndex); |
| 1160 | + assert(() { |
| 1161 | + if (widget == null) { |
| 1162 | + throw FlutterError('separatorBuilder cannot return null.'); |
| 1163 | + } |
| 1164 | + return true; |
| 1165 | + }()); |
| 1166 | + } |
| 1167 | + return widget; |
| 1168 | + }, |
| 1169 | + findChildIndexCallback: findChildIndexCallback, |
| 1170 | + childCount: itemCount == null ? null : math.max(0, itemCount * 2 - 1), |
| 1171 | + addAutomaticKeepAlives: addAutomaticKeepAlives, |
| 1172 | + addRepaintBoundaries: addRepaintBoundaries, |
| 1173 | + addSemanticIndexes: addSemanticIndexes, |
| 1174 | + semanticIndexCallback: (Widget _, int index) { |
| 1175 | + return index.isEven ? index ~/ 2 : null; |
| 1176 | + }, |
| 1177 | + )); |
| 1178 | + |
| 1179 | + /// A sliver that places multiple box children in a linear array along the main |
| 1180 | + /// axis. |
| 1181 | + /// |
| 1182 | + /// This constructor uses a list of [Widget]s to build the sliver. |
| 1183 | + /// |
| 1184 | + /// The `addAutomaticKeepAlives` argument corresponds to the |
| 1185 | + /// [SliverChildBuilderDelegate.addAutomaticKeepAlives] property. The |
| 1186 | + /// `addRepaintBoundaries` argument corresponds to the |
| 1187 | + /// [SliverChildBuilderDelegate.addRepaintBoundaries] property. The |
| 1188 | + /// `addSemanticIndexes` argument corresponds to the |
| 1189 | + /// [SliverChildBuilderDelegate.addSemanticIndexes] property. |
| 1190 | + /// |
| 1191 | + /// {@tool snippet} |
| 1192 | + /// This example, which would be inserted into a [CustomScrollView.slivers] |
| 1193 | + /// list, shows an infinite number of items in varying shades of blue: |
| 1194 | + /// |
| 1195 | + /// ```dart |
| 1196 | + /// SliverList.list( |
| 1197 | + /// children: const <Widget>[ |
| 1198 | + /// Text('Hello'), |
| 1199 | + /// Text('World!'), |
| 1200 | + /// ], |
| 1201 | + /// ); |
| 1202 | + /// ``` |
| 1203 | + /// {@end-tool} |
| 1204 | + SliverList.list({ |
| 1205 | + super.key, |
| 1206 | + required List<Widget> children, |
| 1207 | + bool addAutomaticKeepAlives = true, |
| 1208 | + bool addRepaintBoundaries = true, |
| 1209 | + bool addSemanticIndexes = true, |
| 1210 | + }) : super(delegate: SliverChildListDelegate( |
| 1211 | + children, |
| 1212 | + addAutomaticKeepAlives: addAutomaticKeepAlives, |
| 1213 | + addRepaintBoundaries: addRepaintBoundaries, |
| 1214 | + addSemanticIndexes: addSemanticIndexes, |
| 1215 | + )); |
| 1216 | + |
1038 | 1217 | @override
|
1039 | 1218 | SliverMultiBoxAdaptorElement createElement() => SliverMultiBoxAdaptorElement(this, replaceMovedChildren: true);
|
1040 | 1219 |
|
@@ -1098,6 +1277,116 @@ class SliverFixedExtentList extends SliverMultiBoxAdaptorWidget {
|
1098 | 1277 | required this.itemExtent,
|
1099 | 1278 | });
|
1100 | 1279 |
|
| 1280 | + /// A sliver that places multiple box children in a linear array along the main |
| 1281 | + /// axis. |
| 1282 | + /// |
| 1283 | + /// [SliverFixedExtentList] places its children in a linear array along the main |
| 1284 | + /// axis starting at offset zero and without gaps. Each child is forced to have |
| 1285 | + /// the [itemExtent] in the main axis and the |
| 1286 | + /// [SliverConstraints.crossAxisExtent] in the cross axis. |
| 1287 | + /// |
| 1288 | + /// This constructor is appropriate for sliver lists with a large (or |
| 1289 | + /// infinite) number of children whose extent is already determined. |
| 1290 | + /// |
| 1291 | + /// Providing a non-null `itemCount` improves the ability of the [SliverGrid] |
| 1292 | + /// to estimate the maximum scroll extent. |
| 1293 | + /// |
| 1294 | + /// `itemBuilder` will be called only with indices greater than or equal to |
| 1295 | + /// zero and less than `itemCount`. |
| 1296 | + /// |
| 1297 | + /// {@macro flutter.widgets.ListView.builder.itemBuilder} |
| 1298 | + /// |
| 1299 | + /// The `itemExtent` argument is the extent of each item. |
| 1300 | + /// |
| 1301 | + /// {@macro flutter.widgets.PageView.findChildIndexCallback} |
| 1302 | + /// |
| 1303 | + /// The `addAutomaticKeepAlives` argument corresponds to the |
| 1304 | + /// [SliverChildBuilderDelegate.addAutomaticKeepAlives] property. The |
| 1305 | + /// `addRepaintBoundaries` argument corresponds to the |
| 1306 | + /// [SliverChildBuilderDelegate.addRepaintBoundaries] property. The |
| 1307 | + /// `addSemanticIndexes` argument corresponds to the |
| 1308 | + /// [SliverChildBuilderDelegate.addSemanticIndexes] property. |
| 1309 | + /// {@tool snippet} |
| 1310 | + /// |
| 1311 | + /// This example, which would be inserted into a [CustomScrollView.slivers] |
| 1312 | + /// list, shows an infinite number of items in varying shades of blue: |
| 1313 | + /// |
| 1314 | + /// ```dart |
| 1315 | + /// SliverFixedExtentList.builder( |
| 1316 | + /// itemExtent: 50.0, |
| 1317 | + /// itemBuilder: (BuildContext context, int index) { |
| 1318 | + /// return Container( |
| 1319 | + /// alignment: Alignment.center, |
| 1320 | + /// color: Colors.lightBlue[100 * (index % 9)], |
| 1321 | + /// child: Text('list item $index'), |
| 1322 | + /// ); |
| 1323 | + /// }, |
| 1324 | + /// ) |
| 1325 | + /// ``` |
| 1326 | + /// {@end-tool} |
| 1327 | + SliverFixedExtentList.builder({ |
| 1328 | + super.key, |
| 1329 | + required NullableIndexedWidgetBuilder itemBuilder, |
| 1330 | + required this.itemExtent, |
| 1331 | + ChildIndexGetter? findChildIndexCallback, |
| 1332 | + int? itemCount, |
| 1333 | + bool addAutomaticKeepAlives = true, |
| 1334 | + bool addRepaintBoundaries = true, |
| 1335 | + bool addSemanticIndexes = true, |
| 1336 | + }) : super(delegate: SliverChildBuilderDelegate( |
| 1337 | + itemBuilder, |
| 1338 | + findChildIndexCallback: findChildIndexCallback, |
| 1339 | + childCount: itemCount, |
| 1340 | + addAutomaticKeepAlives: addAutomaticKeepAlives, |
| 1341 | + addRepaintBoundaries: addRepaintBoundaries, |
| 1342 | + addSemanticIndexes: addSemanticIndexes, |
| 1343 | + )); |
| 1344 | + |
| 1345 | + /// A sliver that places multiple box children in a linear array along the main |
| 1346 | + /// axis. |
| 1347 | + /// |
| 1348 | + /// [SliverFixedExtentList] places its children in a linear array along the main |
| 1349 | + /// axis starting at offset zero and without gaps. Each child is forced to have |
| 1350 | + /// the [itemExtent] in the main axis and the |
| 1351 | + /// [SliverConstraints.crossAxisExtent] in the cross axis. |
| 1352 | + /// |
| 1353 | + /// This constructor uses a list of [Widget]s to build the sliver. |
| 1354 | + /// |
| 1355 | + /// The `addAutomaticKeepAlives` argument corresponds to the |
| 1356 | + /// [SliverChildBuilderDelegate.addAutomaticKeepAlives] property. The |
| 1357 | + /// `addRepaintBoundaries` argument corresponds to the |
| 1358 | + /// [SliverChildBuilderDelegate.addRepaintBoundaries] property. The |
| 1359 | + /// `addSemanticIndexes` argument corresponds to the |
| 1360 | + /// [SliverChildBuilderDelegate.addSemanticIndexes] property. |
| 1361 | + /// |
| 1362 | + /// {@tool snippet} |
| 1363 | + /// This example, which would be inserted into a [CustomScrollView.slivers] |
| 1364 | + /// list, shows an infinite number of items in varying shades of blue: |
| 1365 | + /// |
| 1366 | + /// ```dart |
| 1367 | + /// SliverFixedExtentList.list( |
| 1368 | + /// itemExtent: 50.0, |
| 1369 | + /// children: const <Widget>[ |
| 1370 | + /// Text('Hello'), |
| 1371 | + /// Text('World!'), |
| 1372 | + /// ], |
| 1373 | + /// ); |
| 1374 | + /// ``` |
| 1375 | + /// {@end-tool} |
| 1376 | + SliverFixedExtentList.list({ |
| 1377 | + super.key, |
| 1378 | + required List<Widget> children, |
| 1379 | + required this.itemExtent, |
| 1380 | + bool addAutomaticKeepAlives = true, |
| 1381 | + bool addRepaintBoundaries = true, |
| 1382 | + bool addSemanticIndexes = true, |
| 1383 | + }) : super(delegate: SliverChildListDelegate( |
| 1384 | + children, |
| 1385 | + addAutomaticKeepAlives: addAutomaticKeepAlives, |
| 1386 | + addRepaintBoundaries: addRepaintBoundaries, |
| 1387 | + addSemanticIndexes: addSemanticIndexes, |
| 1388 | + )); |
| 1389 | + |
1101 | 1390 | /// The extent the children are forced to have in the main axis.
|
1102 | 1391 | final double itemExtent;
|
1103 | 1392 |
|
|
0 commit comments