mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add convenience constructors for SliverList (#116605)
* init * lint * add the other two slivers * fix lint * add test for sliverlist.separated * add3 more * fix lint and tests * remove trailing spaces * remove trailing spaces 2 * fix lint * fix lint again
This commit is contained in:
parent
bd69ef70ae
commit
a7942e80d4
@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:collection' show HashMap, SplayTreeMap;
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
@ -1035,6 +1036,184 @@ class SliverList extends SliverMultiBoxAdaptorWidget {
|
||||
required super.delegate,
|
||||
});
|
||||
|
||||
/// A sliver that places multiple box children in a linear array along the main
|
||||
/// axis.
|
||||
///
|
||||
/// This constructor is appropriate for sliver lists 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 [SliverGrid]
|
||||
/// to estimate the maximum scroll extent.
|
||||
///
|
||||
/// `itemBuilder` will be called only with indices greater than or equal to
|
||||
/// zero and less than `itemCount`.
|
||||
///
|
||||
/// {@macro flutter.widgets.ListView.builder.itemBuilder}
|
||||
///
|
||||
/// {@macro flutter.widgets.PageView.findChildIndexCallback}
|
||||
///
|
||||
/// The `addAutomaticKeepAlives` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addAutomaticKeepAlives] property. The
|
||||
/// `addRepaintBoundaries` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addRepaintBoundaries] property. The
|
||||
/// `addSemanticIndexes` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addSemanticIndexes] property.
|
||||
///
|
||||
/// {@tool snippet}
|
||||
/// This example, which would be inserted into a [CustomScrollView.slivers]
|
||||
/// list, shows an infinite number of items in varying shades of blue:
|
||||
///
|
||||
/// ```dart
|
||||
/// SliverList.builder(
|
||||
/// itemBuilder: (BuildContext context, int index) {
|
||||
/// return Container(
|
||||
/// alignment: Alignment.center,
|
||||
/// color: Colors.lightBlue[100 * (index % 9)],
|
||||
/// child: Text('list item $index'),
|
||||
/// );
|
||||
/// },
|
||||
/// )
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
SliverList.builder({
|
||||
super.key,
|
||||
required NullableIndexedWidgetBuilder itemBuilder,
|
||||
ChildIndexGetter? findChildIndexCallback,
|
||||
int? itemCount,
|
||||
bool addAutomaticKeepAlives = true,
|
||||
bool addRepaintBoundaries = true,
|
||||
bool addSemanticIndexes = true,
|
||||
}) : super(delegate: SliverChildBuilderDelegate(
|
||||
itemBuilder,
|
||||
findChildIndexCallback: findChildIndexCallback,
|
||||
childCount: itemCount,
|
||||
addAutomaticKeepAlives: addAutomaticKeepAlives,
|
||||
addRepaintBoundaries: addRepaintBoundaries,
|
||||
addSemanticIndexes: addSemanticIndexes,
|
||||
));
|
||||
|
||||
/// A sliver that places multiple box children, separated by box widgets, in a linear array along the main
|
||||
/// axis.
|
||||
///
|
||||
/// This constructor is appropriate for sliver lists 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 [SliverGrid]
|
||||
/// to estimate the maximum scroll extent.
|
||||
///
|
||||
/// `itemBuilder` will be called only with indices greater than or equal to
|
||||
/// zero and less than `itemCount`.
|
||||
///
|
||||
/// {@macro flutter.widgets.ListView.builder.itemBuilder}
|
||||
///
|
||||
/// {@macro flutter.widgets.PageView.findChildIndexCallback}
|
||||
///
|
||||
///
|
||||
/// The `separatorBuilder` is similar to `itemBuilder`, except it is the widget
|
||||
/// that gets placed between itemBuilder(context, index) and itemBuilder(context, index + 1).
|
||||
///
|
||||
/// The `addAutomaticKeepAlives` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addAutomaticKeepAlives] property. The
|
||||
/// `addRepaintBoundaries` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addRepaintBoundaries] property. The
|
||||
/// `addSemanticIndexes` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addSemanticIndexes] property.
|
||||
/// {@tool snippet}
|
||||
///
|
||||
/// This example shows how to create a [SliverList] whose [Container] items
|
||||
/// are separated by [Divider]s.
|
||||
///
|
||||
/// ```dart
|
||||
/// SliverList.separated(
|
||||
/// itemBuilder: (BuildContext context, int index) {
|
||||
/// return Container(
|
||||
/// alignment: Alignment.center,
|
||||
/// color: Colors.lightBlue[100 * (index % 9)],
|
||||
/// child: Text('list item $index'),
|
||||
/// );
|
||||
/// },
|
||||
/// separatorBuilder: (BuildContext context, int index) => const Divider(),
|
||||
/// )
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
SliverList.separated({
|
||||
super.key,
|
||||
required NullableIndexedWidgetBuilder itemBuilder,
|
||||
ChildIndexGetter? findChildIndexCallback,
|
||||
required NullableIndexedWidgetBuilder separatorBuilder,
|
||||
int? itemCount,
|
||||
bool addAutomaticKeepAlives = true,
|
||||
bool addRepaintBoundaries = true,
|
||||
bool addSemanticIndexes = true,
|
||||
}) : assert(itemBuilder != null),
|
||||
assert(separatorBuilder != null),
|
||||
super(delegate: SliverChildBuilderDelegate(
|
||||
(BuildContext context, int index) {
|
||||
final int itemIndex = index ~/ 2;
|
||||
final Widget? widget;
|
||||
if (index.isEven) {
|
||||
widget = itemBuilder(context, itemIndex);
|
||||
} else {
|
||||
widget = separatorBuilder(context, itemIndex);
|
||||
assert(() {
|
||||
if (widget == null) {
|
||||
throw FlutterError('separatorBuilder cannot return null.');
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
}
|
||||
return widget;
|
||||
},
|
||||
findChildIndexCallback: findChildIndexCallback,
|
||||
childCount: itemCount == null ? null : math.max(0, itemCount * 2 - 1),
|
||||
addAutomaticKeepAlives: addAutomaticKeepAlives,
|
||||
addRepaintBoundaries: addRepaintBoundaries,
|
||||
addSemanticIndexes: addSemanticIndexes,
|
||||
semanticIndexCallback: (Widget _, int index) {
|
||||
return index.isEven ? index ~/ 2 : null;
|
||||
},
|
||||
));
|
||||
|
||||
/// A sliver that places multiple box children in a linear array along the main
|
||||
/// axis.
|
||||
///
|
||||
/// This constructor uses a list of [Widget]s to build the sliver.
|
||||
///
|
||||
/// The `addAutomaticKeepAlives` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addAutomaticKeepAlives] property. The
|
||||
/// `addRepaintBoundaries` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addRepaintBoundaries] property. The
|
||||
/// `addSemanticIndexes` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addSemanticIndexes] property.
|
||||
///
|
||||
/// {@tool snippet}
|
||||
/// This example, which would be inserted into a [CustomScrollView.slivers]
|
||||
/// list, shows an infinite number of items in varying shades of blue:
|
||||
///
|
||||
/// ```dart
|
||||
/// SliverList.list(
|
||||
/// children: const <Widget>[
|
||||
/// Text('Hello'),
|
||||
/// Text('World!'),
|
||||
/// ],
|
||||
/// );
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
SliverList.list({
|
||||
super.key,
|
||||
required List<Widget> children,
|
||||
bool addAutomaticKeepAlives = true,
|
||||
bool addRepaintBoundaries = true,
|
||||
bool addSemanticIndexes = true,
|
||||
}) : super(delegate: SliverChildListDelegate(
|
||||
children,
|
||||
addAutomaticKeepAlives: addAutomaticKeepAlives,
|
||||
addRepaintBoundaries: addRepaintBoundaries,
|
||||
addSemanticIndexes: addSemanticIndexes,
|
||||
));
|
||||
|
||||
@override
|
||||
SliverMultiBoxAdaptorElement createElement() => SliverMultiBoxAdaptorElement(this, replaceMovedChildren: true);
|
||||
|
||||
@ -1098,6 +1277,116 @@ class SliverFixedExtentList extends SliverMultiBoxAdaptorWidget {
|
||||
required this.itemExtent,
|
||||
});
|
||||
|
||||
/// A sliver that places multiple box children in a linear array along the main
|
||||
/// axis.
|
||||
///
|
||||
/// [SliverFixedExtentList] places its children in a linear array along the main
|
||||
/// axis starting at offset zero and without gaps. Each child is forced to have
|
||||
/// the [itemExtent] in the main axis and the
|
||||
/// [SliverConstraints.crossAxisExtent] in the cross axis.
|
||||
///
|
||||
/// This constructor is appropriate for sliver lists with a large (or
|
||||
/// infinite) number of children whose extent is already determined.
|
||||
///
|
||||
/// Providing a non-null `itemCount` improves the ability of the [SliverGrid]
|
||||
/// to estimate the maximum scroll extent.
|
||||
///
|
||||
/// `itemBuilder` will be called only with indices greater than or equal to
|
||||
/// zero and less than `itemCount`.
|
||||
///
|
||||
/// {@macro flutter.widgets.ListView.builder.itemBuilder}
|
||||
///
|
||||
/// The `itemExtent` argument is the extent of each item.
|
||||
///
|
||||
/// {@macro flutter.widgets.PageView.findChildIndexCallback}
|
||||
///
|
||||
/// The `addAutomaticKeepAlives` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addAutomaticKeepAlives] property. The
|
||||
/// `addRepaintBoundaries` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addRepaintBoundaries] property. The
|
||||
/// `addSemanticIndexes` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addSemanticIndexes] property.
|
||||
/// {@tool snippet}
|
||||
///
|
||||
/// This example, which would be inserted into a [CustomScrollView.slivers]
|
||||
/// list, shows an infinite number of items in varying shades of blue:
|
||||
///
|
||||
/// ```dart
|
||||
/// SliverFixedExtentList.builder(
|
||||
/// itemExtent: 50.0,
|
||||
/// itemBuilder: (BuildContext context, int index) {
|
||||
/// return Container(
|
||||
/// alignment: Alignment.center,
|
||||
/// color: Colors.lightBlue[100 * (index % 9)],
|
||||
/// child: Text('list item $index'),
|
||||
/// );
|
||||
/// },
|
||||
/// )
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
SliverFixedExtentList.builder({
|
||||
super.key,
|
||||
required NullableIndexedWidgetBuilder itemBuilder,
|
||||
required this.itemExtent,
|
||||
ChildIndexGetter? findChildIndexCallback,
|
||||
int? itemCount,
|
||||
bool addAutomaticKeepAlives = true,
|
||||
bool addRepaintBoundaries = true,
|
||||
bool addSemanticIndexes = true,
|
||||
}) : super(delegate: SliverChildBuilderDelegate(
|
||||
itemBuilder,
|
||||
findChildIndexCallback: findChildIndexCallback,
|
||||
childCount: itemCount,
|
||||
addAutomaticKeepAlives: addAutomaticKeepAlives,
|
||||
addRepaintBoundaries: addRepaintBoundaries,
|
||||
addSemanticIndexes: addSemanticIndexes,
|
||||
));
|
||||
|
||||
/// A sliver that places multiple box children in a linear array along the main
|
||||
/// axis.
|
||||
///
|
||||
/// [SliverFixedExtentList] places its children in a linear array along the main
|
||||
/// axis starting at offset zero and without gaps. Each child is forced to have
|
||||
/// the [itemExtent] in the main axis and the
|
||||
/// [SliverConstraints.crossAxisExtent] in the cross axis.
|
||||
///
|
||||
/// This constructor uses a list of [Widget]s to build the sliver.
|
||||
///
|
||||
/// The `addAutomaticKeepAlives` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addAutomaticKeepAlives] property. The
|
||||
/// `addRepaintBoundaries` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addRepaintBoundaries] property. The
|
||||
/// `addSemanticIndexes` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addSemanticIndexes] property.
|
||||
///
|
||||
/// {@tool snippet}
|
||||
/// This example, which would be inserted into a [CustomScrollView.slivers]
|
||||
/// list, shows an infinite number of items in varying shades of blue:
|
||||
///
|
||||
/// ```dart
|
||||
/// SliverFixedExtentList.list(
|
||||
/// itemExtent: 50.0,
|
||||
/// children: const <Widget>[
|
||||
/// Text('Hello'),
|
||||
/// Text('World!'),
|
||||
/// ],
|
||||
/// );
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
SliverFixedExtentList.list({
|
||||
super.key,
|
||||
required List<Widget> children,
|
||||
required this.itemExtent,
|
||||
bool addAutomaticKeepAlives = true,
|
||||
bool addRepaintBoundaries = true,
|
||||
bool addSemanticIndexes = true,
|
||||
}) : super(delegate: SliverChildListDelegate(
|
||||
children,
|
||||
addAutomaticKeepAlives: addAutomaticKeepAlives,
|
||||
addRepaintBoundaries: addRepaintBoundaries,
|
||||
addSemanticIndexes: addSemanticIndexes,
|
||||
));
|
||||
|
||||
/// The extent the children are forced to have in the main axis.
|
||||
final double itemExtent;
|
||||
|
||||
|
||||
@ -40,6 +40,109 @@ class SliverPrototypeExtentList extends SliverMultiBoxAdaptorWidget {
|
||||
required this.prototypeItem,
|
||||
}) : assert(prototypeItem != null);
|
||||
|
||||
/// A sliver that places its box children in a linear array and constrains them
|
||||
/// to have the same extent as a prototype item along the main axis.
|
||||
///
|
||||
/// This constructor is appropriate for sliver lists with a large (or
|
||||
/// infinite) number of children whose extent is already determined.
|
||||
///
|
||||
/// Providing a non-null `itemCount` improves the ability of the [SliverGrid]
|
||||
/// to estimate the maximum scroll extent.
|
||||
///
|
||||
/// `itemBuilder` will be called only with indices greater than or equal to
|
||||
/// zero and less than `itemCount`.
|
||||
///
|
||||
/// {@macro flutter.widgets.ListView.builder.itemBuilder}
|
||||
///
|
||||
/// The `prototypeItem` argument is used to determine the extent of each item.
|
||||
///
|
||||
/// {@macro flutter.widgets.PageView.findChildIndexCallback}
|
||||
///
|
||||
/// The `addAutomaticKeepAlives` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addAutomaticKeepAlives] property. The
|
||||
/// `addRepaintBoundaries` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addRepaintBoundaries] property. The
|
||||
/// `addSemanticIndexes` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addSemanticIndexes] property.
|
||||
///
|
||||
/// {@tool snippet}
|
||||
/// This example, which would be inserted into a [CustomScrollView.slivers]
|
||||
/// list, shows an infinite number of items in varying shades of blue:
|
||||
///
|
||||
/// ```dart
|
||||
/// SliverPrototypeExtentList.builder(
|
||||
/// prototypeItem: Container(
|
||||
/// alignment: Alignment.center,
|
||||
/// child: const Text('list item prototype'),
|
||||
/// ),
|
||||
/// itemBuilder: (BuildContext context, int index) {
|
||||
/// return Container(
|
||||
/// alignment: Alignment.center,
|
||||
/// color: Colors.lightBlue[100 * (index % 9)],
|
||||
/// child: Text('list item $index'),
|
||||
/// );
|
||||
/// },
|
||||
/// )
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
SliverPrototypeExtentList.builder({
|
||||
super.key,
|
||||
required NullableIndexedWidgetBuilder itemBuilder,
|
||||
required this.prototypeItem,
|
||||
ChildIndexGetter? findChildIndexCallback,
|
||||
int? itemCount,
|
||||
bool addAutomaticKeepAlives = true,
|
||||
bool addRepaintBoundaries = true,
|
||||
bool addSemanticIndexes = true,
|
||||
}) : super(delegate: SliverChildBuilderDelegate(
|
||||
itemBuilder,
|
||||
findChildIndexCallback: findChildIndexCallback,
|
||||
childCount: itemCount,
|
||||
addAutomaticKeepAlives: addAutomaticKeepAlives,
|
||||
addRepaintBoundaries: addRepaintBoundaries,
|
||||
addSemanticIndexes: addSemanticIndexes,
|
||||
));
|
||||
|
||||
/// A sliver that places multiple box children in a linear array along the main
|
||||
/// axis.
|
||||
///
|
||||
/// This constructor uses a list of [Widget]s to build the sliver.
|
||||
///
|
||||
/// The `addAutomaticKeepAlives` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addAutomaticKeepAlives] property. The
|
||||
/// `addRepaintBoundaries` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addRepaintBoundaries] property. The
|
||||
/// `addSemanticIndexes` argument corresponds to the
|
||||
/// [SliverChildBuilderDelegate.addSemanticIndexes] property.
|
||||
///
|
||||
/// {@tool snippet}
|
||||
/// This example, which would be inserted into a [CustomScrollView.slivers]
|
||||
/// list, shows an infinite number of items in varying shades of blue:
|
||||
///
|
||||
/// ```dart
|
||||
/// SliverPrototypeExtentList.list(
|
||||
/// prototypeItem: const Text('Hello'),
|
||||
/// children: const <Widget>[
|
||||
/// Text('Hello'),
|
||||
/// Text('World!'),
|
||||
/// ],
|
||||
/// );
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
SliverPrototypeExtentList.list({
|
||||
super.key,
|
||||
required List<Widget> children,
|
||||
required this.prototypeItem,
|
||||
bool addAutomaticKeepAlives = true,
|
||||
bool addRepaintBoundaries = true,
|
||||
bool addSemanticIndexes = true,
|
||||
}) : super(delegate: SliverChildListDelegate(
|
||||
children,
|
||||
addAutomaticKeepAlives: addAutomaticKeepAlives,
|
||||
addRepaintBoundaries: addRepaintBoundaries,
|
||||
addSemanticIndexes: addSemanticIndexes,
|
||||
));
|
||||
|
||||
/// Defines the main axis extent of all of this sliver's children.
|
||||
///
|
||||
/// The [prototypeItem] is laid out before the rest of the sliver's children
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
class TestItem extends StatelessWidget {
|
||||
@ -41,6 +40,61 @@ Widget buildFrame({ int? count, double? width, double? height, Axis? scrollDirec
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('SliverPrototypeExtentList.builder test', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
body: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
SliverPrototypeExtentList.builder(
|
||||
itemBuilder: (BuildContext context, int index) => TestItem(item: index),
|
||||
prototypeItem: const TestItem(item: -1, height: 100.0),
|
||||
itemCount: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// The viewport is 600 pixels high, lazily created items are 100 pixels high.
|
||||
for (int i = 0; i < 6; i += 1) {
|
||||
final Finder item = find.widgetWithText(Container, 'Item $i');
|
||||
expect(item, findsOneWidget);
|
||||
expect(tester.getTopLeft(item).dy, i * 100.0);
|
||||
expect(tester.getSize(item).height, 100.0);
|
||||
}
|
||||
for (int i = 7; i < 20; i += 1) {
|
||||
expect(find.text('Item $i'), findsNothing);
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('SliverPrototypeExtentList.builder test', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
body: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
SliverPrototypeExtentList.list(
|
||||
prototypeItem: const TestItem(item: -1, height: 100.0),
|
||||
children: <int>[0, 1, 2, 3, 4, 5, 6, 7].map((int index) => TestItem(item: index)).toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// The viewport is 600 pixels high, lazily created items are 100 pixels high.
|
||||
for (int i = 0; i < 6; i += 1) {
|
||||
final Finder item = find.widgetWithText(Container, 'Item $i');
|
||||
expect(item, findsOneWidget);
|
||||
expect(tester.getTopLeft(item).dy, i * 100.0);
|
||||
expect(tester.getSize(item).height, 100.0);
|
||||
}
|
||||
expect(find.text('Item 7'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('SliverPrototypeExtentList vertical scrolling basics', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(buildFrame(count: 20, height: 100.0));
|
||||
|
||||
|
||||
@ -992,6 +992,264 @@ void main() {
|
||||
expect(secondTapped, 1);
|
||||
});
|
||||
|
||||
testWidgets('SliverList.builder can build children', (WidgetTester tester) async {
|
||||
int firstTapped = 0;
|
||||
int secondTapped = 0;
|
||||
final Key key = UniqueKey();
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
key: key,
|
||||
body: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
SliverList.builder(
|
||||
itemCount: 2,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Material(
|
||||
color: index.isEven ? Colors.yellow : Colors.red,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
index.isEven ? firstTapped++ : secondTapped++;
|
||||
},
|
||||
child: Text('Index $index'),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Verify correct hit testing
|
||||
await tester.tap(find.text('Index 0'));
|
||||
expect(firstTapped, 1);
|
||||
expect(secondTapped, 0);
|
||||
firstTapped = 0;
|
||||
await tester.tap(find.text('Index 1'));
|
||||
expect(firstTapped, 0);
|
||||
expect(secondTapped, 1);
|
||||
});
|
||||
|
||||
testWidgets('SliverList.builder can build children', (WidgetTester tester) async {
|
||||
int firstTapped = 0;
|
||||
int secondTapped = 0;
|
||||
final Key key = UniqueKey();
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
key: key,
|
||||
body: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
SliverList.builder(
|
||||
itemCount: 2,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Material(
|
||||
color: index.isEven ? Colors.yellow : Colors.red,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
index.isEven ? firstTapped++ : secondTapped++;
|
||||
},
|
||||
child: Text('Index $index'),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Verify correct hit testing
|
||||
await tester.tap(find.text('Index 0'));
|
||||
expect(firstTapped, 1);
|
||||
expect(secondTapped, 0);
|
||||
firstTapped = 0;
|
||||
await tester.tap(find.text('Index 1'));
|
||||
expect(firstTapped, 0);
|
||||
expect(secondTapped, 1);
|
||||
});
|
||||
|
||||
testWidgets('SliverList.separated can build children', (WidgetTester tester) async {
|
||||
int firstTapped = 0;
|
||||
int secondTapped = 0;
|
||||
final Key key = UniqueKey();
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
key: key,
|
||||
body: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
SliverList.separated(
|
||||
itemCount: 2,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Material(
|
||||
color: index.isEven ? Colors.yellow : Colors.red,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
index.isEven ? firstTapped++ : secondTapped++;
|
||||
},
|
||||
child: Text('Index $index'),
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (BuildContext context, int index) => Text('Separator $index'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Verify correct hit testing
|
||||
await tester.tap(find.text('Index 0'));
|
||||
expect(firstTapped, 1);
|
||||
expect(secondTapped, 0);
|
||||
firstTapped = 0;
|
||||
await tester.tap(find.text('Index 1'));
|
||||
expect(firstTapped, 0);
|
||||
expect(secondTapped, 1);
|
||||
});
|
||||
|
||||
testWidgets('SliverList.separated has correct number of children', (WidgetTester tester) async {
|
||||
final Key key = UniqueKey();
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
key: key,
|
||||
body: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
SliverList.separated(
|
||||
itemCount: 2,
|
||||
itemBuilder: (BuildContext context, int index) => const Text('item'),
|
||||
separatorBuilder: (BuildContext context, int index) => const Text('separator'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
expect(find.text('item'), findsNWidgets(2));
|
||||
expect(find.text('separator'), findsNWidgets(1));
|
||||
});
|
||||
|
||||
testWidgets('SliverList.list can build children', (WidgetTester tester) async {
|
||||
int firstTapped = 0;
|
||||
int secondTapped = 0;
|
||||
final Key key = UniqueKey();
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
key: key,
|
||||
body: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
SliverList.list(
|
||||
children: <Widget>[
|
||||
Material(
|
||||
color: Colors.yellow,
|
||||
child: InkWell(
|
||||
onTap: () => firstTapped++,
|
||||
child: const Text('Index 0'),
|
||||
),
|
||||
),
|
||||
Material(
|
||||
color: Colors.red,
|
||||
child: InkWell(
|
||||
onTap: () => secondTapped++,
|
||||
child: const Text('Index 1'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Verify correct hit testing
|
||||
await tester.tap(find.text('Index 0'));
|
||||
expect(firstTapped, 1);
|
||||
expect(secondTapped, 0);
|
||||
firstTapped = 0;
|
||||
await tester.tap(find.text('Index 1'));
|
||||
expect(firstTapped, 0);
|
||||
expect(secondTapped, 1);
|
||||
});
|
||||
|
||||
testWidgets('SliverFixedExtentList.builder can build children', (WidgetTester tester) async {
|
||||
int firstTapped = 0;
|
||||
int secondTapped = 0;
|
||||
final Key key = UniqueKey();
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
key: key,
|
||||
body: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
SliverFixedExtentList.builder(
|
||||
itemCount: 2,
|
||||
itemExtent: 100,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Material(
|
||||
color: index.isEven ? Colors.yellow : Colors.red,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
index.isEven ? firstTapped++ : secondTapped++;
|
||||
},
|
||||
child: Text('Index $index'),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
// Verify correct hit testing
|
||||
await tester.tap(find.text('Index 0'));
|
||||
expect(firstTapped, 1);
|
||||
expect(secondTapped, 0);
|
||||
firstTapped = 0;
|
||||
await tester.tap(find.text('Index 1'));
|
||||
expect(firstTapped, 0);
|
||||
expect(secondTapped, 1);
|
||||
});
|
||||
|
||||
testWidgets('SliverList.list can build children', (WidgetTester tester) async {
|
||||
int firstTapped = 0;
|
||||
int secondTapped = 0;
|
||||
final Key key = UniqueKey();
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
key: key,
|
||||
body: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
SliverFixedExtentList.list(
|
||||
itemExtent: 100,
|
||||
children: <Widget>[
|
||||
Material(
|
||||
color: Colors.yellow,
|
||||
child: InkWell(
|
||||
onTap: () => firstTapped++,
|
||||
child: const Text('Index 0'),
|
||||
),
|
||||
),
|
||||
Material(
|
||||
color: Colors.red,
|
||||
child: InkWell(
|
||||
onTap: () => secondTapped++,
|
||||
child: const Text('Index 1'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Verify correct hit testing
|
||||
await tester.tap(find.text('Index 0'));
|
||||
expect(firstTapped, 1);
|
||||
expect(secondTapped, 0);
|
||||
firstTapped = 0;
|
||||
await tester.tap(find.text('Index 1'));
|
||||
expect(firstTapped, 0);
|
||||
expect(secondTapped, 1);
|
||||
});
|
||||
|
||||
testWidgets('SliverGrid.builder can build children', (WidgetTester tester) async {
|
||||
int firstTapped = 0;
|
||||
int secondTapped = 0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user