Unverified Commit 3ff76f47 authored by Yuqian Li's avatar Yuqian Li Committed by GitHub

Add clipBehavior to ListView, GridView, PageView (#63147)

These widgets are missing from
https://github.com/flutter/flutter/pull/59364

With this change, developers can use clipBehavior for
https://github.com/flutter/flutter/issues/59424
parent 39a46bed
...@@ -656,7 +656,7 @@ class _NestedScrollViewCustomScrollView extends CustomScrollView { ...@@ -656,7 +656,7 @@ class _NestedScrollViewCustomScrollView extends CustomScrollView {
@required ScrollController controller, @required ScrollController controller,
@required List<Widget> slivers, @required List<Widget> slivers,
@required this.handle, @required this.handle,
@required this.clipBehavior, @required Clip clipBehavior,
DragStartBehavior dragStartBehavior = DragStartBehavior.start, DragStartBehavior dragStartBehavior = DragStartBehavior.start,
String restorationId, String restorationId,
}) : super( }) : super(
...@@ -667,10 +667,10 @@ class _NestedScrollViewCustomScrollView extends CustomScrollView { ...@@ -667,10 +667,10 @@ class _NestedScrollViewCustomScrollView extends CustomScrollView {
slivers: slivers, slivers: slivers,
dragStartBehavior: dragStartBehavior, dragStartBehavior: dragStartBehavior,
restorationId: restorationId, restorationId: restorationId,
clipBehavior: clipBehavior,
); );
final SliverOverlapAbsorberHandle handle; final SliverOverlapAbsorberHandle handle;
final Clip clipBehavior;
@override @override
Widget buildViewport( Widget buildViewport(
......
...@@ -587,7 +587,9 @@ class PageView extends StatefulWidget { ...@@ -587,7 +587,9 @@ class PageView extends StatefulWidget {
this.dragStartBehavior = DragStartBehavior.start, this.dragStartBehavior = DragStartBehavior.start,
this.allowImplicitScrolling = false, this.allowImplicitScrolling = false,
this.restorationId, this.restorationId,
this.clipBehavior = Clip.hardEdge,
}) : assert(allowImplicitScrolling != null), }) : assert(allowImplicitScrolling != null),
assert(clipBehavior != null),
controller = controller ?? _defaultPageController, controller = controller ?? _defaultPageController,
childrenDelegate = SliverChildListDelegate(children), childrenDelegate = SliverChildListDelegate(children),
super(key: key); super(key: key);
...@@ -623,7 +625,9 @@ class PageView extends StatefulWidget { ...@@ -623,7 +625,9 @@ class PageView extends StatefulWidget {
this.dragStartBehavior = DragStartBehavior.start, this.dragStartBehavior = DragStartBehavior.start,
this.allowImplicitScrolling = false, this.allowImplicitScrolling = false,
this.restorationId, this.restorationId,
this.clipBehavior = Clip.hardEdge,
}) : assert(allowImplicitScrolling != null), }) : assert(allowImplicitScrolling != null),
assert(clipBehavior != null),
controller = controller ?? _defaultPageController, controller = controller ?? _defaultPageController,
childrenDelegate = SliverChildBuilderDelegate(itemBuilder, childCount: itemCount), childrenDelegate = SliverChildBuilderDelegate(itemBuilder, childCount: itemCount),
super(key: key); super(key: key);
...@@ -722,8 +726,10 @@ class PageView extends StatefulWidget { ...@@ -722,8 +726,10 @@ class PageView extends StatefulWidget {
this.dragStartBehavior = DragStartBehavior.start, this.dragStartBehavior = DragStartBehavior.start,
this.allowImplicitScrolling = false, this.allowImplicitScrolling = false,
this.restorationId, this.restorationId,
this.clipBehavior = Clip.hardEdge,
}) : assert(childrenDelegate != null), }) : assert(childrenDelegate != null),
assert(allowImplicitScrolling != null), assert(allowImplicitScrolling != null),
assert(clipBehavior != null),
controller = controller ?? _defaultPageController, controller = controller ?? _defaultPageController,
super(key: key); super(key: key);
...@@ -794,6 +800,11 @@ class PageView extends StatefulWidget { ...@@ -794,6 +800,11 @@ class PageView extends StatefulWidget {
/// {@macro flutter.widgets.scrollable.dragStartBehavior} /// {@macro flutter.widgets.scrollable.dragStartBehavior}
final DragStartBehavior dragStartBehavior; final DragStartBehavior dragStartBehavior;
/// {@macro flutter.widgets.Clip}
///
/// Defaults to [Clip.hardEdge].
final Clip clipBehavior;
@override @override
_PageViewState createState() => _PageViewState(); _PageViewState createState() => _PageViewState();
} }
...@@ -856,6 +867,7 @@ class _PageViewState extends State<PageView> { ...@@ -856,6 +867,7 @@ class _PageViewState extends State<PageView> {
cacheExtentStyle: CacheExtentStyle.viewport, cacheExtentStyle: CacheExtentStyle.viewport,
axisDirection: axisDirection, axisDirection: axisDirection,
offset: position, offset: position,
clipBehavior: widget.clipBehavior,
slivers: <Widget>[ slivers: <Widget>[
SliverFillViewport( SliverFillViewport(
viewportFraction: widget.controller.viewportFraction, viewportFraction: widget.controller.viewportFraction,
......
...@@ -92,10 +92,12 @@ abstract class ScrollView extends StatelessWidget { ...@@ -92,10 +92,12 @@ abstract class ScrollView extends StatelessWidget {
this.dragStartBehavior = DragStartBehavior.start, this.dragStartBehavior = DragStartBehavior.start,
this.keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, this.keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
this.restorationId, this.restorationId,
this.clipBehavior = Clip.hardEdge,
}) : assert(scrollDirection != null), }) : assert(scrollDirection != null),
assert(reverse != null), assert(reverse != null),
assert(shrinkWrap != null), assert(shrinkWrap != null),
assert(dragStartBehavior != null), assert(dragStartBehavior != null),
assert(clipBehavior != null),
assert(!(controller != null && primary == true), assert(!(controller != null && primary == true),
'Primary ScrollViews obtain their ScrollController via inheritance from a PrimaryScrollController widget. ' 'Primary ScrollViews obtain their ScrollController via inheritance from a PrimaryScrollController widget. '
'You cannot both set primary to true and pass an explicit controller.' 'You cannot both set primary to true and pass an explicit controller.'
...@@ -264,6 +266,11 @@ abstract class ScrollView extends StatelessWidget { ...@@ -264,6 +266,11 @@ abstract class ScrollView extends StatelessWidget {
/// {@macro flutter.widgets.scrollable.restorationId} /// {@macro flutter.widgets.scrollable.restorationId}
final String restorationId; final String restorationId;
/// {@macro flutter.widgets.Clip}
///
/// Defaults to [Clip.hardEdge].
final Clip clipBehavior;
/// Returns the [AxisDirection] in which the scroll view scrolls. /// Returns the [AxisDirection] in which the scroll view scrolls.
/// ///
/// Combines the [scrollDirection] with the [reverse] boolean to obtain the /// Combines the [scrollDirection] with the [reverse] boolean to obtain the
...@@ -312,6 +319,7 @@ abstract class ScrollView extends StatelessWidget { ...@@ -312,6 +319,7 @@ abstract class ScrollView extends StatelessWidget {
axisDirection: axisDirection, axisDirection: axisDirection,
offset: offset, offset: offset,
slivers: slivers, slivers: slivers,
clipBehavior: clipBehavior,
); );
} }
return Viewport( return Viewport(
...@@ -321,6 +329,7 @@ abstract class ScrollView extends StatelessWidget { ...@@ -321,6 +329,7 @@ abstract class ScrollView extends StatelessWidget {
cacheExtent: cacheExtent, cacheExtent: cacheExtent,
center: center, center: center,
anchor: anchor, anchor: anchor,
clipBehavior: clipBehavior,
); );
} }
...@@ -574,6 +583,7 @@ class CustomScrollView extends ScrollView { ...@@ -574,6 +583,7 @@ class CustomScrollView extends ScrollView {
int semanticChildCount, int semanticChildCount,
DragStartBehavior dragStartBehavior = DragStartBehavior.start, DragStartBehavior dragStartBehavior = DragStartBehavior.start,
String restorationId, String restorationId,
Clip clipBehavior = Clip.hardEdge,
}) : super( }) : super(
key: key, key: key,
scrollDirection: scrollDirection, scrollDirection: scrollDirection,
...@@ -588,6 +598,7 @@ class CustomScrollView extends ScrollView { ...@@ -588,6 +598,7 @@ class CustomScrollView extends ScrollView {
semanticChildCount: semanticChildCount, semanticChildCount: semanticChildCount,
dragStartBehavior: dragStartBehavior, dragStartBehavior: dragStartBehavior,
restorationId: restorationId, restorationId: restorationId,
clipBehavior: clipBehavior,
); );
/// The slivers to place inside the viewport. /// The slivers to place inside the viewport.
...@@ -623,6 +634,7 @@ abstract class BoxScrollView extends ScrollView { ...@@ -623,6 +634,7 @@ abstract class BoxScrollView extends ScrollView {
DragStartBehavior dragStartBehavior = DragStartBehavior.start, DragStartBehavior dragStartBehavior = DragStartBehavior.start,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
String restorationId, String restorationId,
Clip clipBehavior = Clip.hardEdge,
}) : super( }) : super(
key: key, key: key,
scrollDirection: scrollDirection, scrollDirection: scrollDirection,
...@@ -636,6 +648,7 @@ abstract class BoxScrollView extends ScrollView { ...@@ -636,6 +648,7 @@ abstract class BoxScrollView extends ScrollView {
dragStartBehavior: dragStartBehavior, dragStartBehavior: dragStartBehavior,
keyboardDismissBehavior: keyboardDismissBehavior, keyboardDismissBehavior: keyboardDismissBehavior,
restorationId: restorationId, restorationId: restorationId,
clipBehavior: clipBehavior,
); );
/// The amount of space by which to inset the children. /// The amount of space by which to inset the children.
...@@ -1042,6 +1055,7 @@ class ListView extends BoxScrollView { ...@@ -1042,6 +1055,7 @@ class ListView extends BoxScrollView {
DragStartBehavior dragStartBehavior = DragStartBehavior.start, DragStartBehavior dragStartBehavior = DragStartBehavior.start,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
String restorationId, String restorationId,
Clip clipBehavior = Clip.hardEdge,
}) : childrenDelegate = SliverChildListDelegate( }) : childrenDelegate = SliverChildListDelegate(
children, children,
addAutomaticKeepAlives: addAutomaticKeepAlives, addAutomaticKeepAlives: addAutomaticKeepAlives,
...@@ -1062,6 +1076,7 @@ class ListView extends BoxScrollView { ...@@ -1062,6 +1076,7 @@ class ListView extends BoxScrollView {
dragStartBehavior: dragStartBehavior, dragStartBehavior: dragStartBehavior,
keyboardDismissBehavior: keyboardDismissBehavior, keyboardDismissBehavior: keyboardDismissBehavior,
restorationId: restorationId, restorationId: restorationId,
clipBehavior: clipBehavior,
); );
/// Creates a scrollable, linear array of widgets that are created on demand. /// Creates a scrollable, linear array of widgets that are created on demand.
...@@ -1115,6 +1130,7 @@ class ListView extends BoxScrollView { ...@@ -1115,6 +1130,7 @@ class ListView extends BoxScrollView {
DragStartBehavior dragStartBehavior = DragStartBehavior.start, DragStartBehavior dragStartBehavior = DragStartBehavior.start,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
String restorationId, String restorationId,
Clip clipBehavior = Clip.hardEdge,
}) : assert(itemCount == null || itemCount >= 0), }) : assert(itemCount == null || itemCount >= 0),
assert(semanticChildCount == null || semanticChildCount <= itemCount), assert(semanticChildCount == null || semanticChildCount <= itemCount),
childrenDelegate = SliverChildBuilderDelegate( childrenDelegate = SliverChildBuilderDelegate(
...@@ -1138,6 +1154,7 @@ class ListView extends BoxScrollView { ...@@ -1138,6 +1154,7 @@ class ListView extends BoxScrollView {
dragStartBehavior: dragStartBehavior, dragStartBehavior: dragStartBehavior,
keyboardDismissBehavior: keyboardDismissBehavior, keyboardDismissBehavior: keyboardDismissBehavior,
restorationId: restorationId, restorationId: restorationId,
clipBehavior: clipBehavior,
); );
/// Creates a fixed-length scrollable linear array of list "items" separated /// Creates a fixed-length scrollable linear array of list "items" separated
...@@ -1206,6 +1223,7 @@ class ListView extends BoxScrollView { ...@@ -1206,6 +1223,7 @@ class ListView extends BoxScrollView {
DragStartBehavior dragStartBehavior = DragStartBehavior.start, DragStartBehavior dragStartBehavior = DragStartBehavior.start,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
String restorationId, String restorationId,
Clip clipBehavior = Clip.hardEdge,
}) : assert(itemBuilder != null), }) : assert(itemBuilder != null),
assert(separatorBuilder != null), assert(separatorBuilder != null),
assert(itemCount != null && itemCount >= 0), assert(itemCount != null && itemCount >= 0),
...@@ -1249,6 +1267,7 @@ class ListView extends BoxScrollView { ...@@ -1249,6 +1267,7 @@ class ListView extends BoxScrollView {
dragStartBehavior: dragStartBehavior, dragStartBehavior: dragStartBehavior,
keyboardDismissBehavior: keyboardDismissBehavior, keyboardDismissBehavior: keyboardDismissBehavior,
restorationId: restorationId, restorationId: restorationId,
clipBehavior: clipBehavior,
); );
/// Creates a scrollable, linear array of widgets with a custom child model. /// Creates a scrollable, linear array of widgets with a custom child model.
...@@ -1349,6 +1368,7 @@ class ListView extends BoxScrollView { ...@@ -1349,6 +1368,7 @@ class ListView extends BoxScrollView {
DragStartBehavior dragStartBehavior = DragStartBehavior.start, DragStartBehavior dragStartBehavior = DragStartBehavior.start,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
String restorationId, String restorationId,
Clip clipBehavior = Clip.hardEdge,
}) : assert(childrenDelegate != null), }) : assert(childrenDelegate != null),
super( super(
key: key, key: key,
...@@ -1364,6 +1384,7 @@ class ListView extends BoxScrollView { ...@@ -1364,6 +1384,7 @@ class ListView extends BoxScrollView {
dragStartBehavior: dragStartBehavior, dragStartBehavior: dragStartBehavior,
keyboardDismissBehavior: keyboardDismissBehavior, keyboardDismissBehavior: keyboardDismissBehavior,
restorationId: restorationId, restorationId: restorationId,
clipBehavior: clipBehavior,
); );
/// If non-null, forces the children to have the given extent in the scroll /// If non-null, forces the children to have the given extent in the scroll
...@@ -1642,6 +1663,7 @@ class GridView extends BoxScrollView { ...@@ -1642,6 +1663,7 @@ class GridView extends BoxScrollView {
List<Widget> children = const <Widget>[], List<Widget> children = const <Widget>[],
int semanticChildCount, int semanticChildCount,
DragStartBehavior dragStartBehavior = DragStartBehavior.start, DragStartBehavior dragStartBehavior = DragStartBehavior.start,
Clip clipBehavior = Clip.hardEdge,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
String restorationId, String restorationId,
}) : assert(gridDelegate != null), }) : assert(gridDelegate != null),
...@@ -1665,6 +1687,7 @@ class GridView extends BoxScrollView { ...@@ -1665,6 +1687,7 @@ class GridView extends BoxScrollView {
dragStartBehavior: dragStartBehavior, dragStartBehavior: dragStartBehavior,
keyboardDismissBehavior: keyboardDismissBehavior, keyboardDismissBehavior: keyboardDismissBehavior,
restorationId: restorationId, restorationId: restorationId,
clipBehavior: clipBehavior,
); );
/// Creates a scrollable, 2D array of widgets that are created on demand. /// Creates a scrollable, 2D array of widgets that are created on demand.
...@@ -1706,6 +1729,7 @@ class GridView extends BoxScrollView { ...@@ -1706,6 +1729,7 @@ class GridView extends BoxScrollView {
DragStartBehavior dragStartBehavior = DragStartBehavior.start, DragStartBehavior dragStartBehavior = DragStartBehavior.start,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
String restorationId, String restorationId,
Clip clipBehavior = Clip.hardEdge,
}) : assert(gridDelegate != null), }) : assert(gridDelegate != null),
childrenDelegate = SliverChildBuilderDelegate( childrenDelegate = SliverChildBuilderDelegate(
itemBuilder, itemBuilder,
...@@ -1728,6 +1752,7 @@ class GridView extends BoxScrollView { ...@@ -1728,6 +1752,7 @@ class GridView extends BoxScrollView {
dragStartBehavior: dragStartBehavior, dragStartBehavior: dragStartBehavior,
keyboardDismissBehavior: keyboardDismissBehavior, keyboardDismissBehavior: keyboardDismissBehavior,
restorationId: restorationId, restorationId: restorationId,
clipBehavior: clipBehavior,
); );
/// Creates a scrollable, 2D array of widgets with both a custom /// Creates a scrollable, 2D array of widgets with both a custom
...@@ -1753,6 +1778,7 @@ class GridView extends BoxScrollView { ...@@ -1753,6 +1778,7 @@ class GridView extends BoxScrollView {
DragStartBehavior dragStartBehavior = DragStartBehavior.start, DragStartBehavior dragStartBehavior = DragStartBehavior.start,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
String restorationId, String restorationId,
Clip clipBehavior = Clip.hardEdge,
}) : assert(gridDelegate != null), }) : assert(gridDelegate != null),
assert(childrenDelegate != null), assert(childrenDelegate != null),
super( super(
...@@ -1769,6 +1795,7 @@ class GridView extends BoxScrollView { ...@@ -1769,6 +1795,7 @@ class GridView extends BoxScrollView {
dragStartBehavior: dragStartBehavior, dragStartBehavior: dragStartBehavior,
keyboardDismissBehavior: keyboardDismissBehavior, keyboardDismissBehavior: keyboardDismissBehavior,
restorationId: restorationId, restorationId: restorationId,
clipBehavior: clipBehavior,
); );
/// Creates a scrollable, 2D array of widgets with a fixed number of tiles in /// Creates a scrollable, 2D array of widgets with a fixed number of tiles in
...@@ -1807,6 +1834,7 @@ class GridView extends BoxScrollView { ...@@ -1807,6 +1834,7 @@ class GridView extends BoxScrollView {
DragStartBehavior dragStartBehavior = DragStartBehavior.start, DragStartBehavior dragStartBehavior = DragStartBehavior.start,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
String restorationId, String restorationId,
Clip clipBehavior = Clip.hardEdge,
}) : gridDelegate = SliverGridDelegateWithFixedCrossAxisCount( }) : gridDelegate = SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: crossAxisCount, crossAxisCount: crossAxisCount,
mainAxisSpacing: mainAxisSpacing, mainAxisSpacing: mainAxisSpacing,
...@@ -1833,6 +1861,7 @@ class GridView extends BoxScrollView { ...@@ -1833,6 +1861,7 @@ class GridView extends BoxScrollView {
dragStartBehavior: dragStartBehavior, dragStartBehavior: dragStartBehavior,
keyboardDismissBehavior: keyboardDismissBehavior, keyboardDismissBehavior: keyboardDismissBehavior,
restorationId: restorationId, restorationId: restorationId,
clipBehavior: clipBehavior,
); );
/// Creates a scrollable, 2D array of widgets with tiles that each have a /// Creates a scrollable, 2D array of widgets with tiles that each have a
...@@ -1871,6 +1900,7 @@ class GridView extends BoxScrollView { ...@@ -1871,6 +1900,7 @@ class GridView extends BoxScrollView {
DragStartBehavior dragStartBehavior = DragStartBehavior.start, DragStartBehavior dragStartBehavior = DragStartBehavior.start,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
String restorationId, String restorationId,
Clip clipBehavior = Clip.hardEdge,
}) : gridDelegate = SliverGridDelegateWithMaxCrossAxisExtent( }) : gridDelegate = SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: maxCrossAxisExtent, maxCrossAxisExtent: maxCrossAxisExtent,
mainAxisSpacing: mainAxisSpacing, mainAxisSpacing: mainAxisSpacing,
...@@ -1897,6 +1927,7 @@ class GridView extends BoxScrollView { ...@@ -1897,6 +1927,7 @@ class GridView extends BoxScrollView {
dragStartBehavior: dragStartBehavior, dragStartBehavior: dragStartBehavior,
keyboardDismissBehavior: keyboardDismissBehavior, keyboardDismissBehavior: keyboardDismissBehavior,
restorationId: restorationId, restorationId: restorationId,
clipBehavior: clipBehavior,
); );
/// A delegate that controls the layout of the children within the [GridView]. /// A delegate that controls the layout of the children within the [GridView].
......
...@@ -6,9 +6,11 @@ ...@@ -6,9 +6,11 @@
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/gestures.dart' show DragStartBehavior; import 'package:flutter/gestures.dart' show DragStartBehavior;
import '../rendering/mock_canvas.dart'; import '../rendering/mock_canvas.dart';
import '../rendering/rendering_tester.dart';
import 'states.dart'; import 'states.dart';
void main() { void main() {
...@@ -602,4 +604,106 @@ void main() { ...@@ -602,4 +604,106 @@ void main() {
expect(find.byKey(const ValueKey<int>(4)), findsOneWidget); expect(find.byKey(const ValueKey<int>(4)), findsOneWidget);
expect(counters[4], 2); expect(counters[4], 2);
}); });
testWidgets('GridView respects clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: GridView(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
children: <Widget>[Container(height: 2000.0)],
),
),
);
// 1st, check that the render object has received the default clip behavior.
final RenderViewport renderObject = tester.allRenderObjects.whereType<RenderViewport>().first;
expect(renderObject.clipBehavior, equals(Clip.hardEdge));
// 2nd, check that the painting context has received the default clip behavior.
final TestClipPaintingContext context = TestClipPaintingContext();
renderObject.paint(context, Offset.zero);
expect(context.clipBehavior, equals(Clip.hardEdge));
// 3rd, pump a new widget to check that the render object can update its clip behavior.
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: GridView(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
children: <Widget>[Container(height: 2000.0)],
clipBehavior: Clip.antiAlias,
),
),
);
expect(renderObject.clipBehavior, equals(Clip.antiAlias));
// 4th, check that a non-default clip behavior can be sent to the painting context.
renderObject.paint(context, Offset.zero);
expect(context.clipBehavior, equals(Clip.antiAlias));
});
testWidgets('GridView.builder respects clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemCount: 10,
itemBuilder: (BuildContext _, int __) => Container(height: 2000.0),
clipBehavior: Clip.antiAlias,
),
),
);
final RenderViewport renderObject = tester.allRenderObjects.whereType<RenderViewport>().first;
expect(renderObject.clipBehavior, equals(Clip.antiAlias));
});
testWidgets('GridView.custom respects clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: GridView.custom(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
childrenDelegate: SliverChildBuilderDelegate(
(BuildContext context, int index) => Container(height: 2000.0),
childCount: 1,
),
clipBehavior: Clip.antiAlias,
),
),
);
final RenderViewport renderObject = tester.allRenderObjects.whereType<RenderViewport>().first;
expect(renderObject.clipBehavior, equals(Clip.antiAlias));
});
testWidgets('GridView.count respects clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: GridView.count(
crossAxisCount: 3,
children: <Widget>[Container(height: 2000.0)],
clipBehavior: Clip.antiAlias,
),
),
);
final RenderViewport renderObject = tester.allRenderObjects.whereType<RenderViewport>().first;
expect(renderObject.clipBehavior, equals(Clip.antiAlias));
});
testWidgets('GridView.extent respects clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: GridView.extent(
maxCrossAxisExtent: 1000,
children: <Widget>[Container(height: 2000.0)],
clipBehavior: Clip.antiAlias,
),
),
);
final RenderViewport renderObject = tester.allRenderObjects.whereType<RenderViewport>().first;
expect(renderObject.clipBehavior, equals(Clip.antiAlias));
});
} }
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
// @dart = 2.8 // @dart = 2.8
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import '../rendering/mock_canvas.dart'; import '../rendering/mock_canvas.dart';
import '../rendering/rendering_tester.dart';
class TestSliverChildListDelegate extends SliverChildListDelegate { class TestSliverChildListDelegate extends SliverChildListDelegate {
TestSliverChildListDelegate(List<Widget> children) : super(children); TestSliverChildListDelegate(List<Widget> children) : super(children);
...@@ -575,4 +578,88 @@ void main() { ...@@ -575,4 +578,88 @@ void main() {
await tester.pumpWidget(buildListView(scrollDirection: Axis.horizontal)); await tester.pumpWidget(buildListView(scrollDirection: Axis.horizontal));
expect(controller.position.viewportDimension, 100.0); expect(controller.position.viewportDimension, 100.0);
}); });
testWidgets('ListView respects clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: ListView(
children: <Widget>[Container(height: 2000.0)],
),
),
);
// 1st, check that the render object has received the default clip behavior.
final RenderViewport renderObject = tester.allRenderObjects.whereType<RenderViewport>().first;
expect(renderObject.clipBehavior, equals(Clip.hardEdge));
// 2nd, check that the painting context has received the default clip behavior.
final TestClipPaintingContext context = TestClipPaintingContext();
renderObject.paint(context, Offset.zero);
expect(context.clipBehavior, equals(Clip.hardEdge));
// 3rd, pump a new widget to check that the render object can update its clip behavior.
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: ListView(
children: <Widget>[Container(height: 2000.0)],
clipBehavior: Clip.antiAlias,
),
),
);
expect(renderObject.clipBehavior, equals(Clip.antiAlias));
// 4th, check that a non-default clip behavior can be sent to the painting context.
renderObject.paint(context, Offset.zero);
expect(context.clipBehavior, equals(Clip.antiAlias));
});
testWidgets('ListView.builder respects clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: ListView.builder(
itemCount: 10,
itemBuilder: (BuildContext _, int __) => Container(height: 2000.0),
clipBehavior: Clip.antiAlias,
),
),
);
final RenderViewport renderObject = tester.allRenderObjects.whereType<RenderViewport>().first;
expect(renderObject.clipBehavior, equals(Clip.antiAlias));
});
testWidgets('ListView.custom respects clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: ListView.custom(
childrenDelegate: SliverChildBuilderDelegate(
(BuildContext context, int index) => Container(height: 2000.0),
childCount: 1,
),
clipBehavior: Clip.antiAlias,
),
),
);
final RenderViewport renderObject = tester.allRenderObjects.whereType<RenderViewport>().first;
expect(renderObject.clipBehavior, equals(Clip.antiAlias));
});
testWidgets('ListView.separated respects clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: ListView.separated(
itemCount: 10,
itemBuilder: (BuildContext _, int __) => Container(height: 2000.0),
separatorBuilder: (BuildContext _, int __) => const Divider(),
clipBehavior: Clip.antiAlias,
),
),
);
final RenderViewport renderObject = tester.allRenderObjects.whereType<RenderViewport>().first;
expect(renderObject.clipBehavior, equals(Clip.antiAlias));
});
} }
...@@ -10,6 +10,7 @@ import 'package:flutter/rendering.dart'; ...@@ -10,6 +10,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter/gestures.dart' show DragStartBehavior; import 'package:flutter/gestures.dart' show DragStartBehavior;
import '../rendering/rendering_tester.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
import 'states.dart'; import 'states.dart';
...@@ -951,4 +952,40 @@ void main() { ...@@ -951,4 +952,40 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('PageView respects clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: PageView(
children: <Widget>[Container(height: 2000.0)],
),
),
);
// 1st, check that the render object has received the default clip behavior.
final RenderViewport renderObject = tester.allRenderObjects.whereType<RenderViewport>().first;
expect(renderObject.clipBehavior, equals(Clip.hardEdge));
// 2nd, check that the painting context has received the default clip behavior.
final TestClipPaintingContext context = TestClipPaintingContext();
renderObject.paint(context, Offset.zero);
expect(context.clipBehavior, equals(Clip.hardEdge));
// 3rd, pump a new widget to check that the render object can update its clip behavior.
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: PageView(
children: <Widget>[Container(height: 2000.0)],
clipBehavior: Clip.antiAlias,
),
),
);
expect(renderObject.clipBehavior, equals(Clip.antiAlias));
// 4th, check that a non-default clip behavior can be sent to the painting context.
renderObject.paint(context, Offset.zero);
expect(context.clipBehavior, equals(Clip.antiAlias));
});
} }
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