Skip to content

Commit 41a13a3

Browse files
authored
Add SliverGrid.builder constructor (#113116)
1 parent 3eef3ff commit 41a13a3

File tree

3 files changed

+86
-3
lines changed

3 files changed

+86
-3
lines changed

packages/flutter/lib/src/widgets/scroll_view.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,13 +1757,14 @@ class GridView extends BoxScrollView {
17571757
///
17581758
/// {@macro flutter.widgets.PageView.findChildIndexCallback}
17591759
///
1760-
/// The [gridDelegate] argument must not be null.
1760+
/// The [gridDelegate] argument is required.
17611761
///
17621762
/// The `addAutomaticKeepAlives` argument corresponds to the
17631763
/// [SliverChildBuilderDelegate.addAutomaticKeepAlives] property. The
17641764
/// `addRepaintBoundaries` argument corresponds to the
1765-
/// [SliverChildBuilderDelegate.addRepaintBoundaries] property. Both must not
1766-
/// be null.
1765+
/// [SliverChildBuilderDelegate.addRepaintBoundaries] property. The
1766+
/// `addSemanticIndexes` argument corresponds to the
1767+
/// [SliverChildBuilderDelegate.addSemanticIndexes] property.
17671768
GridView.builder({
17681769
super.key,
17691770
super.scrollDirection,

packages/flutter/lib/src/widgets/sliver.dart

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,49 @@ class SliverGrid extends SliverMultiBoxAdaptorWidget {
11661166
required this.gridDelegate,
11671167
});
11681168

1169+
/// A sliver that creates a 2D array of widgets that are created on demand.
1170+
///
1171+
/// This constructor is appropriate for sliver grids with a large (or
1172+
/// infinite) number of children because the builder is called only for those
1173+
/// children that are actually visible.
1174+
///
1175+
/// Providing a non-null `itemCount` improves the ability of the [SliverGrid]
1176+
/// to estimate the maximum scroll extent.
1177+
///
1178+
/// `itemBuilder` will be called only with indices greater than or equal to
1179+
/// zero and less than `itemCount`.
1180+
///
1181+
/// {@macro flutter.widgets.ListView.builder.itemBuilder}
1182+
///
1183+
/// {@macro flutter.widgets.PageView.findChildIndexCallback}
1184+
///
1185+
/// The [gridDelegate] argument is required.
1186+
///
1187+
/// The `addAutomaticKeepAlives` argument corresponds to the
1188+
/// [SliverChildBuilderDelegate.addAutomaticKeepAlives] property. The
1189+
/// `addRepaintBoundaries` argument corresponds to the
1190+
/// [SliverChildBuilderDelegate.addRepaintBoundaries] property. The
1191+
/// `addSemanticIndexes` argument corresponds to the
1192+
/// [SliverChildBuilderDelegate.addSemanticIndexes] property.
1193+
SliverGrid.builder({
1194+
super.key,
1195+
required this.gridDelegate,
1196+
required NullableIndexedWidgetBuilder itemBuilder,
1197+
ChildIndexGetter? findChildIndexCallback,
1198+
int? itemCount,
1199+
bool addAutomaticKeepAlives = true,
1200+
bool addRepaintBoundaries = true,
1201+
bool addSemanticIndexes = true,
1202+
}) : assert(gridDelegate != null),
1203+
super(delegate: SliverChildBuilderDelegate(
1204+
itemBuilder,
1205+
findChildIndexCallback: findChildIndexCallback,
1206+
childCount: itemCount,
1207+
addAutomaticKeepAlives: addAutomaticKeepAlives,
1208+
addRepaintBoundaries: addRepaintBoundaries,
1209+
addSemanticIndexes: addSemanticIndexes,
1210+
));
1211+
11691212
/// Creates a sliver that places multiple box children in a two dimensional
11701213
/// arrangement with a fixed number of tiles in the cross axis.
11711214
///

packages/flutter/test/widgets/slivers_test.dart

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,45 @@ void main() {
991991
expect(firstTapped, 1);
992992
expect(secondTapped, 1);
993993
});
994+
995+
testWidgets('SliverGrid.builder can build children', (WidgetTester tester) async {
996+
int firstTapped = 0;
997+
int secondTapped = 0;
998+
final Key key = UniqueKey();
999+
await tester.pumpWidget(MaterialApp(
1000+
home: Scaffold(
1001+
key: key,
1002+
body: CustomScrollView(
1003+
slivers: <Widget>[
1004+
SliverGrid.builder(
1005+
itemCount: 2,
1006+
itemBuilder: (BuildContext context, int index) {
1007+
return Material(
1008+
color: index.isEven ? Colors.yellow : Colors.red,
1009+
child: InkWell(
1010+
onTap: () {
1011+
index.isEven ? firstTapped++ : secondTapped++;
1012+
},
1013+
child: Text('Index $index'),
1014+
),
1015+
);
1016+
},
1017+
gridDelegate: _TestArbitrarySliverGridDelegate(),
1018+
),
1019+
],
1020+
),
1021+
),
1022+
));
1023+
1024+
// Verify correct hit testing
1025+
await tester.tap(find.text('Index 0'));
1026+
expect(firstTapped, 1);
1027+
expect(secondTapped, 0);
1028+
firstTapped = 0;
1029+
await tester.tap(find.text('Index 1'));
1030+
expect(firstTapped, 0);
1031+
expect(secondTapped, 1);
1032+
});
9941033
}
9951034

9961035
bool isRight(Offset a, Offset b) => b.dx > a.dx;

0 commit comments

Comments
 (0)