Unverified Commit e0ac5da1 authored by TheBiirb's avatar TheBiirb Committed by GitHub

Added clipBehavior to Overlay, Flow, AnimatedSize and AndroidView (#65910)

parent 3e838da9
...@@ -81,10 +81,13 @@ class RenderAnimatedSize extends RenderAligningShiftedBox { ...@@ -81,10 +81,13 @@ class RenderAnimatedSize extends RenderAligningShiftedBox {
AlignmentGeometry alignment = Alignment.center, AlignmentGeometry alignment = Alignment.center,
TextDirection? textDirection, TextDirection? textDirection,
RenderBox? child, RenderBox? child,
Clip clipBehavior = Clip.hardEdge,
}) : assert(vsync != null), }) : assert(vsync != null),
assert(duration != null), assert(duration != null),
assert(curve != null), assert(curve != null),
assert(clipBehavior != null),
_vsync = vsync, _vsync = vsync,
_clipBehavior = clipBehavior,
super(child: child, alignment: alignment, textDirection: textDirection) { super(child: child, alignment: alignment, textDirection: textDirection) {
_controller = AnimationController( _controller = AnimationController(
vsync: vsync, vsync: vsync,
...@@ -139,6 +142,20 @@ class RenderAnimatedSize extends RenderAligningShiftedBox { ...@@ -139,6 +142,20 @@ class RenderAnimatedSize extends RenderAligningShiftedBox {
_animation.curve = value; _animation.curve = value;
} }
/// {@macro flutter.widgets.Clip}
///
/// Defaults to [Clip.hardEdge], and must not be null.
Clip get clipBehavior => _clipBehavior;
Clip _clipBehavior = Clip.hardEdge;
set clipBehavior(Clip value) {
assert(value != null);
if (value != _clipBehavior) {
_clipBehavior = value;
markNeedsPaint();
markNeedsSemanticsUpdate();
}
}
/// Whether the size is being currently animated towards the child's size. /// Whether the size is being currently animated towards the child's size.
/// ///
/// See [RenderAnimatedSizeState] for situations when we may not be animating /// See [RenderAnimatedSizeState] for situations when we may not be animating
...@@ -275,9 +292,9 @@ class RenderAnimatedSize extends RenderAligningShiftedBox { ...@@ -275,9 +292,9 @@ class RenderAnimatedSize extends RenderAligningShiftedBox {
@override @override
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null && _hasVisualOverflow) { if (child != null && _hasVisualOverflow && clipBehavior != Clip.none) {
final Rect rect = Offset.zero & size; final Rect rect = Offset.zero & size;
context.pushClipRect(needsCompositing, offset, rect, super.paint); context.pushClipRect(needsCompositing, offset, rect, super.paint, clipBehavior: clipBehavior);
} else { } else {
super.paint(context, offset); super.paint(context, offset);
} }
......
...@@ -181,8 +181,11 @@ class RenderFlow extends RenderBox ...@@ -181,8 +181,11 @@ class RenderFlow extends RenderBox
RenderFlow({ RenderFlow({
List<RenderBox>? children, List<RenderBox>? children,
required FlowDelegate delegate, required FlowDelegate delegate,
Clip clipBehavior = Clip.hardEdge,
}) : assert(delegate != null), }) : assert(delegate != null),
_delegate = delegate { assert(clipBehavior != null),
_delegate = delegate,
_clipBehavior = clipBehavior {
addAll(children); addAll(children);
} }
...@@ -221,6 +224,20 @@ class RenderFlow extends RenderBox ...@@ -221,6 +224,20 @@ class RenderFlow extends RenderBox
} }
} }
/// {@macro flutter.widgets.Clip}
///
/// Defaults to [Clip.hardEdge], and must not be null.
Clip get clipBehavior => _clipBehavior;
Clip _clipBehavior = Clip.hardEdge;
set clipBehavior(Clip value) {
assert(value != null);
if (value != _clipBehavior) {
_clipBehavior = value;
markNeedsPaint();
markNeedsSemanticsUpdate();
}
}
@override @override
void attach(PipelineOwner owner) { void attach(PipelineOwner owner) {
super.attach(owner); super.attach(owner);
...@@ -365,7 +382,11 @@ class RenderFlow extends RenderBox ...@@ -365,7 +382,11 @@ class RenderFlow extends RenderBox
@override @override
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
context.pushClipRect(needsCompositing, offset, Offset.zero & size, _paintWithDelegate); if (clipBehavior == Clip.none) {
_paintWithDelegate(context, offset);
} else {
context.pushClipRect(needsCompositing, offset, Offset.zero & size, _paintWithDelegate, clipBehavior: clipBehavior);
}
} }
@override @override
......
...@@ -83,10 +83,13 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin { ...@@ -83,10 +83,13 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin {
required AndroidViewController viewController, required AndroidViewController viewController,
required PlatformViewHitTestBehavior hitTestBehavior, required PlatformViewHitTestBehavior hitTestBehavior,
required Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers, required Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers,
Clip clipBehavior = Clip.hardEdge,
}) : assert(viewController != null), }) : assert(viewController != null),
assert(hitTestBehavior != null), assert(hitTestBehavior != null),
assert(gestureRecognizers != null), assert(gestureRecognizers != null),
_viewController = viewController { assert(clipBehavior != null),
_viewController = viewController,
_clipBehavior = clipBehavior {
_viewController.pointTransformer = (Offset offset) => globalToLocal(offset); _viewController.pointTransformer = (Offset offset) => globalToLocal(offset);
updateGestureRecognizers(gestureRecognizers); updateGestureRecognizers(gestureRecognizers);
_viewController.addOnPlatformViewCreatedListener(_onPlatformViewCreated); _viewController.addOnPlatformViewCreatedListener(_onPlatformViewCreated);
...@@ -115,6 +118,20 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin { ...@@ -115,6 +118,20 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin {
_viewController.addOnPlatformViewCreatedListener(_onPlatformViewCreated); _viewController.addOnPlatformViewCreatedListener(_onPlatformViewCreated);
} }
/// {@macro flutter.widgets.Clip}
///
/// Defaults to [Clip.hardEdge], and must not be null.
Clip get clipBehavior => _clipBehavior;
Clip _clipBehavior = Clip.hardEdge;
set clipBehavior(Clip value) {
assert(value != null);
if (value != _clipBehavior) {
_clipBehavior = value;
markNeedsPaint();
markNeedsSemanticsUpdate();
}
}
void _onPlatformViewCreated(int id) { void _onPlatformViewCreated(int id) {
markNeedsSemanticsUpdate(); markNeedsSemanticsUpdate();
} }
...@@ -188,8 +205,8 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin { ...@@ -188,8 +205,8 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin {
// Clip the texture if it's going to paint out of the bounds of the renter box // Clip the texture if it's going to paint out of the bounds of the renter box
// (see comment in _paintTexture for an explanation of when this happens). // (see comment in _paintTexture for an explanation of when this happens).
if (size.width < _currentAndroidViewSize.width || size.height < _currentAndroidViewSize.height) { if (size.width < _currentAndroidViewSize.width || size.height < _currentAndroidViewSize.height && clipBehavior != Clip.none) {
context.pushClipRect(true, offset, offset & size, _paintTexture); context.pushClipRect(true, offset, offset & size, _paintTexture, clipBehavior: clipBehavior);
return; return;
} }
......
...@@ -61,7 +61,9 @@ class AnimatedSize extends SingleChildRenderObjectWidget { ...@@ -61,7 +61,9 @@ class AnimatedSize extends SingleChildRenderObjectWidget {
required this.duration, required this.duration,
this.reverseDuration, this.reverseDuration,
required this.vsync, required this.vsync,
}) : super(key: key, child: child); this.clipBehavior = Clip.hardEdge,
}) : assert(clipBehavior != null),
super(key: key, child: child);
/// The alignment of the child within the parent when the parent is not yet /// The alignment of the child within the parent when the parent is not yet
/// the same size as the child. /// the same size as the child.
...@@ -101,6 +103,11 @@ class AnimatedSize extends SingleChildRenderObjectWidget { ...@@ -101,6 +103,11 @@ class AnimatedSize extends SingleChildRenderObjectWidget {
/// The [TickerProvider] for this widget. /// The [TickerProvider] for this widget.
final TickerProvider vsync; final TickerProvider vsync;
/// {@macro flutter.widgets.Clip}
///
/// Defaults to [Clip.hardEdge], and must not be null.
final Clip clipBehavior;
@override @override
RenderAnimatedSize createRenderObject(BuildContext context) { RenderAnimatedSize createRenderObject(BuildContext context) {
return RenderAnimatedSize( return RenderAnimatedSize(
...@@ -110,6 +117,7 @@ class AnimatedSize extends SingleChildRenderObjectWidget { ...@@ -110,6 +117,7 @@ class AnimatedSize extends SingleChildRenderObjectWidget {
curve: curve, curve: curve,
vsync: vsync, vsync: vsync,
textDirection: Directionality.of(context), textDirection: Directionality.of(context),
clipBehavior: clipBehavior,
); );
} }
...@@ -121,7 +129,8 @@ class AnimatedSize extends SingleChildRenderObjectWidget { ...@@ -121,7 +129,8 @@ class AnimatedSize extends SingleChildRenderObjectWidget {
..reverseDuration = reverseDuration ..reverseDuration = reverseDuration
..curve = curve ..curve = curve
..vsync = vsync ..vsync = vsync
..textDirection = Directionality.of(context); ..textDirection = Directionality.of(context)
..clipBehavior = clipBehavior;
} }
@override @override
......
...@@ -5091,7 +5091,9 @@ class Flow extends MultiChildRenderObjectWidget { ...@@ -5091,7 +5091,9 @@ class Flow extends MultiChildRenderObjectWidget {
Key? key, Key? key,
required this.delegate, required this.delegate,
List<Widget> children = const <Widget>[], List<Widget> children = const <Widget>[],
this.clipBehavior = Clip.hardEdge,
}) : assert(delegate != null), }) : assert(delegate != null),
assert(clipBehavior != null),
super(key: key, children: RepaintBoundary.wrapAll(children)); super(key: key, children: RepaintBoundary.wrapAll(children));
// https://github.com/dart-lang/sdk/issues/29277 // https://github.com/dart-lang/sdk/issues/29277
...@@ -5106,18 +5108,26 @@ class Flow extends MultiChildRenderObjectWidget { ...@@ -5106,18 +5108,26 @@ class Flow extends MultiChildRenderObjectWidget {
Key? key, Key? key,
required this.delegate, required this.delegate,
List<Widget> children = const <Widget>[], List<Widget> children = const <Widget>[],
this.clipBehavior = Clip.hardEdge,
}) : assert(delegate != null), }) : assert(delegate != null),
assert(clipBehavior != null),
super(key: key, children: children); super(key: key, children: children);
/// The delegate that controls the transformation matrices of the children. /// The delegate that controls the transformation matrices of the children.
final FlowDelegate delegate; final FlowDelegate delegate;
/// {@macro flutter.widgets.Clip}
///
/// Defaults to [Clip.none], and must not be null.
final Clip clipBehavior;
@override @override
RenderFlow createRenderObject(BuildContext context) => RenderFlow(delegate: delegate); RenderFlow createRenderObject(BuildContext context) => RenderFlow(delegate: delegate, clipBehavior: clipBehavior);
@override @override
void updateRenderObject(BuildContext context, RenderFlow renderObject) { void updateRenderObject(BuildContext context, RenderFlow renderObject) {
renderObject.delegate = delegate; renderObject.delegate = delegate;
renderObject.clipBehavior = clipBehavior;
} }
} }
......
...@@ -213,7 +213,9 @@ class Overlay extends StatefulWidget { ...@@ -213,7 +213,9 @@ class Overlay extends StatefulWidget {
const Overlay({ const Overlay({
Key? key, Key? key,
this.initialEntries = const <OverlayEntry>[], this.initialEntries = const <OverlayEntry>[],
this.clipBehavior = Clip.hardEdge,
}) : assert(initialEntries != null), }) : assert(initialEntries != null),
assert(clipBehavior != null),
super(key: key); super(key: key);
/// The entries to include in the overlay initially. /// The entries to include in the overlay initially.
...@@ -231,6 +233,11 @@ class Overlay extends StatefulWidget { ...@@ -231,6 +233,11 @@ class Overlay extends StatefulWidget {
/// To remove an entry from an [Overlay], use [OverlayEntry.remove]. /// To remove an entry from an [Overlay], use [OverlayEntry.remove].
final List<OverlayEntry> initialEntries; final List<OverlayEntry> initialEntries;
/// {@macro flutter.widgets.Clip}
///
/// Defaults to [Clip.hardEdge], and must not be null.
final Clip clipBehavior;
/// The state from the closest instance of this class that encloses the given context. /// The state from the closest instance of this class that encloses the given context.
/// ///
/// In debug mode, if the `debugRequiredFor` argument is provided then this /// In debug mode, if the `debugRequiredFor` argument is provided then this
...@@ -470,6 +477,7 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin { ...@@ -470,6 +477,7 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin {
return _Theatre( return _Theatre(
skipCount: children.length - onstageCount, skipCount: children.length - onstageCount,
children: children.reversed.toList(growable: false), children: children.reversed.toList(growable: false),
clipBehavior: widget.clipBehavior,
); );
} }
...@@ -490,15 +498,19 @@ class _Theatre extends MultiChildRenderObjectWidget { ...@@ -490,15 +498,19 @@ class _Theatre extends MultiChildRenderObjectWidget {
_Theatre({ _Theatre({
Key? key, Key? key,
this.skipCount = 0, this.skipCount = 0,
this.clipBehavior = Clip.hardEdge,
List<Widget> children = const <Widget>[], List<Widget> children = const <Widget>[],
}) : assert(skipCount != null), }) : assert(skipCount != null),
assert(skipCount >= 0), assert(skipCount >= 0),
assert(children != null), assert(children != null),
assert(children.length >= skipCount), assert(children.length >= skipCount),
assert(clipBehavior != null),
super(key: key, children: children); super(key: key, children: children);
final int skipCount; final int skipCount;
final Clip clipBehavior;
@override @override
_TheatreElement createElement() => _TheatreElement(this); _TheatreElement createElement() => _TheatreElement(this);
...@@ -507,6 +519,7 @@ class _Theatre extends MultiChildRenderObjectWidget { ...@@ -507,6 +519,7 @@ class _Theatre extends MultiChildRenderObjectWidget {
return _RenderTheatre( return _RenderTheatre(
skipCount: skipCount, skipCount: skipCount,
textDirection: Directionality.of(context)!, textDirection: Directionality.of(context)!,
clipBehavior: clipBehavior,
); );
} }
...@@ -514,7 +527,8 @@ class _Theatre extends MultiChildRenderObjectWidget { ...@@ -514,7 +527,8 @@ class _Theatre extends MultiChildRenderObjectWidget {
void updateRenderObject(BuildContext context, _RenderTheatre renderObject) { void updateRenderObject(BuildContext context, _RenderTheatre renderObject) {
renderObject renderObject
..skipCount = skipCount ..skipCount = skipCount
..textDirection = Directionality.of(context)!; ..textDirection = Directionality.of(context)!
..clipBehavior = clipBehavior;
} }
@override @override
...@@ -545,11 +559,14 @@ class _RenderTheatre extends RenderBox with ContainerRenderObjectMixin<RenderBox ...@@ -545,11 +559,14 @@ class _RenderTheatre extends RenderBox with ContainerRenderObjectMixin<RenderBox
List<RenderBox>? children, List<RenderBox>? children,
required TextDirection textDirection, required TextDirection textDirection,
int skipCount = 0, int skipCount = 0,
Clip clipBehavior = Clip.hardEdge,
}) : assert(skipCount != null), }) : assert(skipCount != null),
assert(skipCount >= 0), assert(skipCount >= 0),
assert(textDirection != null), assert(textDirection != null),
assert(clipBehavior != null),
_textDirection = textDirection, _textDirection = textDirection,
_skipCount = skipCount { _skipCount = skipCount,
_clipBehavior = clipBehavior {
addAll(children); addAll(children);
} }
...@@ -593,6 +610,20 @@ class _RenderTheatre extends RenderBox with ContainerRenderObjectMixin<RenderBox ...@@ -593,6 +610,20 @@ class _RenderTheatre extends RenderBox with ContainerRenderObjectMixin<RenderBox
} }
} }
/// {@macro flutter.widgets.Clip}
///
/// Defaults to [Clip.hardEdge], and must not be null.
Clip get clipBehavior => _clipBehavior;
Clip _clipBehavior = Clip.hardEdge;
set clipBehavior(Clip value) {
assert(value != null);
if (value != _clipBehavior) {
_clipBehavior = value;
markNeedsPaint();
markNeedsSemanticsUpdate();
}
}
RenderBox? get _firstOnstageChild { RenderBox? get _firstOnstageChild {
if (skipCount == super.childCount) { if (skipCount == super.childCount) {
return null; return null;
...@@ -724,8 +755,8 @@ class _RenderTheatre extends RenderBox with ContainerRenderObjectMixin<RenderBox ...@@ -724,8 +755,8 @@ class _RenderTheatre extends RenderBox with ContainerRenderObjectMixin<RenderBox
@override @override
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (_hasVisualOverflow) { if (_hasVisualOverflow && clipBehavior != Clip.none) {
context.pushClipRect(needsCompositing, offset, Offset.zero & size, paintStack); context.pushClipRect(needsCompositing, offset, Offset.zero & size, paintStack, clipBehavior: clipBehavior);
} else { } else {
paintStack(context, offset); paintStack(context, offset);
} }
......
...@@ -71,9 +71,11 @@ class AndroidView extends StatefulWidget { ...@@ -71,9 +71,11 @@ class AndroidView extends StatefulWidget {
this.gestureRecognizers, this.gestureRecognizers,
this.creationParams, this.creationParams,
this.creationParamsCodec, this.creationParamsCodec,
this.clipBehavior = Clip.hardEdge,
}) : assert(viewType != null), }) : assert(viewType != null),
assert(hitTestBehavior != null), assert(hitTestBehavior != null),
assert(creationParams == null || creationParamsCodec != null), assert(creationParams == null || creationParamsCodec != null),
assert(clipBehavior != null),
super(key: key); super(key: key);
/// The unique identifier for Android view type to be embedded by this widget. /// The unique identifier for Android view type to be embedded by this widget.
...@@ -181,6 +183,11 @@ class AndroidView extends StatefulWidget { ...@@ -181,6 +183,11 @@ class AndroidView extends StatefulWidget {
/// This must not be null if [creationParams] is not null. /// This must not be null if [creationParams] is not null.
final MessageCodec<dynamic>? creationParamsCodec; final MessageCodec<dynamic>? creationParamsCodec;
/// {@macro flutter.widgets.Clip}
///
/// Defaults to [Clip.hardEdge], and must not be null.
final Clip clipBehavior;
@override @override
State<AndroidView> createState() => _AndroidViewState(); State<AndroidView> createState() => _AndroidViewState();
} }
...@@ -434,6 +441,7 @@ class _AndroidViewState extends State<AndroidView> { ...@@ -434,6 +441,7 @@ class _AndroidViewState extends State<AndroidView> {
controller: _controller, controller: _controller,
hitTestBehavior: widget.hitTestBehavior, hitTestBehavior: widget.hitTestBehavior,
gestureRecognizers: widget.gestureRecognizers ?? _emptyRecognizersSet, gestureRecognizers: widget.gestureRecognizers ?? _emptyRecognizersSet,
clipBehavior: widget.clipBehavior,
), ),
); );
} }
...@@ -643,14 +651,17 @@ class _AndroidPlatformView extends LeafRenderObjectWidget { ...@@ -643,14 +651,17 @@ class _AndroidPlatformView extends LeafRenderObjectWidget {
required this.controller, required this.controller,
required this.hitTestBehavior, required this.hitTestBehavior,
required this.gestureRecognizers, required this.gestureRecognizers,
this.clipBehavior = Clip.hardEdge,
}) : assert(controller != null), }) : assert(controller != null),
assert(hitTestBehavior != null), assert(hitTestBehavior != null),
assert(gestureRecognizers != null), assert(gestureRecognizers != null),
assert(clipBehavior != null),
super(key: key); super(key: key);
final AndroidViewController controller; final AndroidViewController controller;
final PlatformViewHitTestBehavior hitTestBehavior; final PlatformViewHitTestBehavior hitTestBehavior;
final Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers; final Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers;
final Clip clipBehavior;
@override @override
RenderObject createRenderObject(BuildContext context) => RenderObject createRenderObject(BuildContext context) =>
...@@ -658,6 +669,7 @@ class _AndroidPlatformView extends LeafRenderObjectWidget { ...@@ -658,6 +669,7 @@ class _AndroidPlatformView extends LeafRenderObjectWidget {
viewController: controller, viewController: controller,
hitTestBehavior: hitTestBehavior, hitTestBehavior: hitTestBehavior,
gestureRecognizers: gestureRecognizers, gestureRecognizers: gestureRecognizers,
clipBehavior: clipBehavior,
); );
@override @override
...@@ -665,6 +677,7 @@ class _AndroidPlatformView extends LeafRenderObjectWidget { ...@@ -665,6 +677,7 @@ class _AndroidPlatformView extends LeafRenderObjectWidget {
renderObject.viewController = controller; renderObject.viewController = controller;
renderObject.hitTestBehavior = hitTestBehavior; renderObject.hitTestBehavior = hitTestBehavior;
renderObject.updateGestureRecognizers(gestureRecognizers); renderObject.updateGestureRecognizers(gestureRecognizers);
renderObject.clipBehavior = clipBehavior;
} }
} }
......
...@@ -281,5 +281,41 @@ void main() { ...@@ -281,5 +281,41 @@ void main() {
await tester.pump(const Duration(milliseconds: 10)); await tester.pump(const Duration(milliseconds: 10));
} }
}); });
testWidgets('can set and update clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(
Center(
child: AnimatedSize(
duration: const Duration(milliseconds: 200),
vsync: tester,
child: const SizedBox(
width: 100.0,
height: 100.0,
),
),
),
);
// By default, clipBehavior should be Clip.hardEdge
final RenderAnimatedSize renderObject = tester.renderObject(find.byType(AnimatedSize));
expect(renderObject.clipBehavior, equals(Clip.hardEdge));
for(final Clip clip in Clip.values) {
await tester.pumpWidget(
Center(
child: AnimatedSize(
duration: const Duration(milliseconds: 200),
vsync: tester,
clipBehavior: clip,
child: const SizedBox(
width: 100.0,
height: 100.0,
),
),
),
);
expect(renderObject.clipBehavior, clip);
}
});
}); });
} }
...@@ -157,4 +157,62 @@ void main() { ...@@ -157,4 +157,62 @@ void main() {
expect(opacityLayer.alpha, equals(opacity * 255)); expect(opacityLayer.alpha, equals(opacity * 255));
expect(layer.firstChild, isA<TransformLayer>()); expect(layer.firstChild, isA<TransformLayer>());
}); });
testWidgets('Flow can set and update clipBehavior', (WidgetTester tester) async {
const double opacity = 0.2;
await tester.pumpWidget(
Flow(
delegate: OpacityFlowDelegate(opacity),
children: const <Widget>[
SizedBox(width: 100.0, height: 100.0),
],
),
);
// By default, clipBehavior should be Clip.hardEdge
final RenderFlow renderObject = tester.renderObject(find.byType(Flow));
expect(renderObject.clipBehavior, equals(Clip.hardEdge));
for(final Clip clip in Clip.values) {
await tester.pumpWidget(
Flow(
delegate: OpacityFlowDelegate(opacity),
children: const <Widget>[
SizedBox(width: 100.0, height: 100.0),
],
clipBehavior: clip,
),
);
expect(renderObject.clipBehavior, clip);
}
});
testWidgets('Flow.unwrapped can set and update clipBehavior', (WidgetTester tester) async {
const double opacity = 0.2;
await tester.pumpWidget(
Flow.unwrapped(
delegate: OpacityFlowDelegate(opacity),
children: const <Widget>[
SizedBox(width: 100.0, height: 100.0),
],
),
);
// By default, clipBehavior should be Clip.hardEdge
final RenderFlow renderObject = tester.renderObject(find.byType(Flow));
expect(renderObject.clipBehavior, equals(Clip.hardEdge));
for(final Clip clip in Clip.values) {
await tester.pumpWidget(
Flow.unwrapped(
delegate: OpacityFlowDelegate(opacity),
children: const <Widget>[
SizedBox(width: 100.0, height: 100.0),
],
clipBehavior: clip,
),
);
expect(renderObject.clipBehavior, clip);
}
});
} }
...@@ -1002,7 +1002,7 @@ void main() { ...@@ -1002,7 +1002,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Can used Positioned within OverlayEntry', (WidgetTester tester) async { testWidgets('Can use Positioned within OverlayEntry', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -1024,6 +1024,42 @@ void main() { ...@@ -1024,6 +1024,42 @@ void main() {
expect(tester.getTopLeft(find.text('positioned child')), const Offset(145, 123)); expect(tester.getTopLeft(find.text('positioned child')), const Offset(145, 123));
}); });
testWidgets('Overlay can set and update clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Overlay(
initialEntries: <OverlayEntry>[
OverlayEntry(
builder: (BuildContext context) => Container(),
),
],
),
),
);
// By default, clipBehavior should be Clip.hardEdge
final dynamic renderObject = tester.renderObject(find.byType(Overlay));
expect(renderObject.clipBehavior, equals(Clip.hardEdge));
for(final Clip clip in Clip.values) {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Overlay(
initialEntries: <OverlayEntry>[
OverlayEntry(
builder: (BuildContext context) => Container(),
),
],
clipBehavior: clip,
),
),
);
expect(renderObject.clipBehavior, clip);
}
});
} }
class StatefulTestWidget extends StatefulWidget { class StatefulTestWidget extends StatefulWidget {
......
...@@ -1103,6 +1103,52 @@ void main() { ...@@ -1103,6 +1103,52 @@ void main() {
expect(viewsController.lastClearedFocusViewId, currentViewId + 1); expect(viewsController.lastClearedFocusViewId, currentViewId + 1);
}); });
testWidgets('can set and update clipBehavior', (WidgetTester tester) async {
final FakeAndroidPlatformViewsController viewsController = FakeAndroidPlatformViewsController();
viewsController.registerViewType('webview');
await tester.pumpWidget(
const Center(
child: SizedBox(
width: 200.0,
height: 100.0,
child: AndroidView(
viewType: 'webview',
layoutDirection: TextDirection.ltr,
),
),
),
);
// By default, clipBehavior should be Clip.hardEdge
final RenderAndroidView renderObject = tester.renderObject(
find.descendant(
of: find.byType(AndroidView),
matching: find.byWidgetPredicate(
(Widget widget) => widget.runtimeType.toString() == '_AndroidPlatformView',
),
),
);
expect(renderObject.clipBehavior, equals(Clip.hardEdge));
for(final Clip clip in Clip.values) {
await tester.pumpWidget(
Center(
child: SizedBox(
width: 200.0,
height: 100.0,
child: AndroidView(
viewType: 'webview',
layoutDirection: TextDirection.ltr,
clipBehavior: clip,
),
),
),
);
expect(renderObject.clipBehavior, clip);
}
});
}); });
group('AndroidViewSurface', () { group('AndroidViewSurface', () {
......
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