Commit a57018a4 authored by Adam Barth's avatar Adam Barth Committed by GitHub

Add GridView.builder (#9522)

This constructor makes it easier to use a GridView with a builder
callback.

Fixes #8952
parent 95418482
...@@ -313,7 +313,7 @@ class PageView extends StatefulWidget { ...@@ -313,7 +313,7 @@ class PageView extends StatefulWidget {
PageController controller, PageController controller,
this.physics, this.physics,
this.onPageChanged, this.onPageChanged,
IndexedWidgetBuilder itemBuilder, @required IndexedWidgetBuilder itemBuilder,
int itemCount, int itemCount,
}) : controller = controller ?? _defaultPageController, }) : controller = controller ?? _defaultPageController,
childrenDelegate = new SliverChildBuilderDelegate(itemBuilder, childCount: itemCount), childrenDelegate = new SliverChildBuilderDelegate(itemBuilder, childCount: itemCount),
......
...@@ -386,7 +386,7 @@ class ListView extends BoxScrollView { ...@@ -386,7 +386,7 @@ class ListView extends BoxScrollView {
bool shrinkWrap: false, bool shrinkWrap: false,
EdgeInsets padding, EdgeInsets padding,
this.itemExtent, this.itemExtent,
IndexedWidgetBuilder itemBuilder, @required IndexedWidgetBuilder itemBuilder,
int itemCount, int itemCount,
}) : childrenDelegate = new SliverChildBuilderDelegate(itemBuilder, childCount: itemCount), super( }) : childrenDelegate = new SliverChildBuilderDelegate(itemBuilder, childCount: itemCount), super(
key: key, key: key,
...@@ -473,8 +473,11 @@ class ListView extends BoxScrollView { ...@@ -473,8 +473,11 @@ class ListView extends BoxScrollView {
/// overlapping. /// overlapping.
/// ///
/// To create a grid with a large (or infinite) number of children, use the /// To create a grid with a large (or infinite) number of children, use the
/// [GridView.custom] constructor with either a [SliverChildBuilderDelegate] or /// [GridView.builder] constructor with either a
/// a custom [SliverChildDelegate]. /// [SliverGridDelegateWithFixedCrossAxisCount] or a
/// [SliverGridDelegateWithMaxCrossAxisExtent] for the [gridDelegate].
///
/// To use a custom [SliverChildDelegate], use [GridView.custom].
/// ///
/// To create a linear array of children, use a [ListView]. /// To create a linear array of children, use a [ListView].
/// ///
...@@ -520,11 +523,49 @@ class GridView extends BoxScrollView { ...@@ -520,11 +523,49 @@ class GridView extends BoxScrollView {
assert(gridDelegate != null); assert(gridDelegate != null);
} }
/// Creates a scrollable, 2D array of widgets that are created on demand.
///
/// This constructor is appropriate for grid views with a large (or infinite)
/// number of children because the builder is called only for those children
/// that are actually visible.
///
/// Providing a non-null [itemCount] improves the ability of the [GridView] to
/// estimate the maximum scroll extent.
///
/// [itemBuilder] will be called only with indices greater than or equal to
/// zero and less than [itemCount].
///
/// The [gridDelegate] argument must not be null.
GridView.builder({
Key key,
Axis scrollDirection: Axis.vertical,
bool reverse: false,
ScrollController controller,
bool primary,
ScrollPhysics physics,
bool shrinkWrap: false,
EdgeInsets padding,
@required this.gridDelegate,
@required IndexedWidgetBuilder itemBuilder,
int itemCount,
}) : childrenDelegate = new SliverChildBuilderDelegate(itemBuilder, childCount: itemCount), super(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding,
) {
assert(gridDelegate != null);
}
/// Creates a scrollable, 2D array of widgets with both a custom /// Creates a scrollable, 2D array of widgets with both a custom
/// [SliverGridDelegate] and a custom [SliverChildDelegate]. /// [SliverGridDelegate] and a custom [SliverChildDelegate].
/// ///
/// To use an [IndexedWidgetBuilder] callback to build children, use the /// To use an [IndexedWidgetBuilder] callback to build children, either use
/// [SliverChildBuilderDelegate]. /// a [SliverChildBuilderDelegate] or use the [GridView.builder] constructor.
/// ///
/// The [gridDelegate] and [childrenDelegate] arguments must not be null. /// The [gridDelegate] and [childrenDelegate] arguments must not be null.
GridView.custom({ GridView.custom({
......
...@@ -369,6 +369,24 @@ void main() { ...@@ -369,6 +369,24 @@ void main() {
expect(find.text('19'), findsOneWidget); expect(find.text('19'), findsOneWidget);
}); });
testWidgets('GridView.builder control test', (WidgetTester tester) async {
await tester.pumpWidget(new GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
),
shrinkWrap: true,
itemCount: 20,
itemBuilder: (BuildContext context, int index) {
return new Container(
child: new Text('$index'),
);
},
));
expect(find.text('0'), findsOneWidget);
expect(find.text('11'), findsOneWidget);
expect(find.text('12'), findsNothing);
});
// TODO(ianh): can you tap a grid cell that is slightly off the bottom of the screen? // TODO(ianh): can you tap a grid cell that is slightly off the bottom of the screen?
// (try it with the flutter_gallery Grid demo) // (try it with the flutter_gallery Grid demo)
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment