Added clipBehavior to Overlay, Flow, AnimatedSize and AndroidView (#65910)
This commit is contained in:
@@ -81,10 +81,13 @@ class RenderAnimatedSize extends RenderAligningShiftedBox {
|
||||
AlignmentGeometry alignment = Alignment.center,
|
||||
TextDirection? textDirection,
|
||||
RenderBox? child,
|
||||
Clip clipBehavior = Clip.hardEdge,
|
||||
}) : assert(vsync != null),
|
||||
assert(duration != null),
|
||||
assert(curve != null),
|
||||
assert(clipBehavior != null),
|
||||
_vsync = vsync,
|
||||
_clipBehavior = clipBehavior,
|
||||
super(child: child, alignment: alignment, textDirection: textDirection) {
|
||||
_controller = AnimationController(
|
||||
vsync: vsync,
|
||||
@@ -139,6 +142,20 @@ class RenderAnimatedSize extends RenderAligningShiftedBox {
|
||||
_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.
|
||||
///
|
||||
/// See [RenderAnimatedSizeState] for situations when we may not be animating
|
||||
@@ -275,9 +292,9 @@ class RenderAnimatedSize extends RenderAligningShiftedBox {
|
||||
|
||||
@override
|
||||
void paint(PaintingContext context, Offset offset) {
|
||||
if (child != null && _hasVisualOverflow) {
|
||||
if (child != null && _hasVisualOverflow && clipBehavior != Clip.none) {
|
||||
final Rect rect = Offset.zero & size;
|
||||
context.pushClipRect(needsCompositing, offset, rect, super.paint);
|
||||
context.pushClipRect(needsCompositing, offset, rect, super.paint, clipBehavior: clipBehavior);
|
||||
} else {
|
||||
super.paint(context, offset);
|
||||
}
|
||||
|
||||
@@ -181,8 +181,11 @@ class RenderFlow extends RenderBox
|
||||
RenderFlow({
|
||||
List<RenderBox>? children,
|
||||
required FlowDelegate delegate,
|
||||
Clip clipBehavior = Clip.hardEdge,
|
||||
}) : assert(delegate != null),
|
||||
_delegate = delegate {
|
||||
assert(clipBehavior != null),
|
||||
_delegate = delegate,
|
||||
_clipBehavior = clipBehavior {
|
||||
addAll(children);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
void attach(PipelineOwner owner) {
|
||||
super.attach(owner);
|
||||
@@ -365,7 +382,11 @@ class RenderFlow extends RenderBox
|
||||
|
||||
@override
|
||||
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
|
||||
|
||||
@@ -83,10 +83,13 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin {
|
||||
required AndroidViewController viewController,
|
||||
required PlatformViewHitTestBehavior hitTestBehavior,
|
||||
required Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers,
|
||||
Clip clipBehavior = Clip.hardEdge,
|
||||
}) : assert(viewController != null),
|
||||
assert(hitTestBehavior != null),
|
||||
assert(gestureRecognizers != null),
|
||||
_viewController = viewController {
|
||||
assert(clipBehavior != null),
|
||||
_viewController = viewController,
|
||||
_clipBehavior = clipBehavior {
|
||||
_viewController.pointTransformer = (Offset offset) => globalToLocal(offset);
|
||||
updateGestureRecognizers(gestureRecognizers);
|
||||
_viewController.addOnPlatformViewCreatedListener(_onPlatformViewCreated);
|
||||
@@ -115,6 +118,20 @@ class RenderAndroidView extends RenderBox with _PlatformViewGestureMixin {
|
||||
_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) {
|
||||
markNeedsSemanticsUpdate();
|
||||
}
|
||||
@@ -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
|
||||
// (see comment in _paintTexture for an explanation of when this happens).
|
||||
if (size.width < _currentAndroidViewSize.width || size.height < _currentAndroidViewSize.height) {
|
||||
context.pushClipRect(true, offset, offset & size, _paintTexture);
|
||||
if (size.width < _currentAndroidViewSize.width || size.height < _currentAndroidViewSize.height && clipBehavior != Clip.none) {
|
||||
context.pushClipRect(true, offset, offset & size, _paintTexture, clipBehavior: clipBehavior);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,9 @@ class AnimatedSize extends SingleChildRenderObjectWidget {
|
||||
required this.duration,
|
||||
this.reverseDuration,
|
||||
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 same size as the child.
|
||||
@@ -101,6 +103,11 @@ class AnimatedSize extends SingleChildRenderObjectWidget {
|
||||
/// The [TickerProvider] for this widget.
|
||||
final TickerProvider vsync;
|
||||
|
||||
/// {@macro flutter.widgets.Clip}
|
||||
///
|
||||
/// Defaults to [Clip.hardEdge], and must not be null.
|
||||
final Clip clipBehavior;
|
||||
|
||||
@override
|
||||
RenderAnimatedSize createRenderObject(BuildContext context) {
|
||||
return RenderAnimatedSize(
|
||||
@@ -110,6 +117,7 @@ class AnimatedSize extends SingleChildRenderObjectWidget {
|
||||
curve: curve,
|
||||
vsync: vsync,
|
||||
textDirection: Directionality.of(context),
|
||||
clipBehavior: clipBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -121,7 +129,8 @@ class AnimatedSize extends SingleChildRenderObjectWidget {
|
||||
..reverseDuration = reverseDuration
|
||||
..curve = curve
|
||||
..vsync = vsync
|
||||
..textDirection = Directionality.of(context);
|
||||
..textDirection = Directionality.of(context)
|
||||
..clipBehavior = clipBehavior;
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -5091,7 +5091,9 @@ class Flow extends MultiChildRenderObjectWidget {
|
||||
Key? key,
|
||||
required this.delegate,
|
||||
List<Widget> children = const <Widget>[],
|
||||
this.clipBehavior = Clip.hardEdge,
|
||||
}) : assert(delegate != null),
|
||||
assert(clipBehavior != null),
|
||||
super(key: key, children: RepaintBoundary.wrapAll(children));
|
||||
// https://github.com/dart-lang/sdk/issues/29277
|
||||
|
||||
@@ -5106,18 +5108,26 @@ class Flow extends MultiChildRenderObjectWidget {
|
||||
Key? key,
|
||||
required this.delegate,
|
||||
List<Widget> children = const <Widget>[],
|
||||
this.clipBehavior = Clip.hardEdge,
|
||||
}) : assert(delegate != null),
|
||||
assert(clipBehavior != null),
|
||||
super(key: key, children: children);
|
||||
|
||||
/// The delegate that controls the transformation matrices of the children.
|
||||
final FlowDelegate delegate;
|
||||
|
||||
/// {@macro flutter.widgets.Clip}
|
||||
///
|
||||
/// Defaults to [Clip.none], and must not be null.
|
||||
final Clip clipBehavior;
|
||||
|
||||
@override
|
||||
RenderFlow createRenderObject(BuildContext context) => RenderFlow(delegate: delegate);
|
||||
RenderFlow createRenderObject(BuildContext context) => RenderFlow(delegate: delegate, clipBehavior: clipBehavior);
|
||||
|
||||
@override
|
||||
void updateRenderObject(BuildContext context, RenderFlow renderObject) {
|
||||
renderObject.delegate = delegate;
|
||||
renderObject.clipBehavior = clipBehavior;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +213,9 @@ class Overlay extends StatefulWidget {
|
||||
const Overlay({
|
||||
Key? key,
|
||||
this.initialEntries = const <OverlayEntry>[],
|
||||
this.clipBehavior = Clip.hardEdge,
|
||||
}) : assert(initialEntries != null),
|
||||
assert(clipBehavior != null),
|
||||
super(key: key);
|
||||
|
||||
/// The entries to include in the overlay initially.
|
||||
@@ -231,6 +233,11 @@ class Overlay extends StatefulWidget {
|
||||
/// To remove an entry from an [Overlay], use [OverlayEntry.remove].
|
||||
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.
|
||||
///
|
||||
/// In debug mode, if the `debugRequiredFor` argument is provided then this
|
||||
@@ -470,6 +477,7 @@ class OverlayState extends State<Overlay> with TickerProviderStateMixin {
|
||||
return _Theatre(
|
||||
skipCount: children.length - onstageCount,
|
||||
children: children.reversed.toList(growable: false),
|
||||
clipBehavior: widget.clipBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -490,15 +498,19 @@ class _Theatre extends MultiChildRenderObjectWidget {
|
||||
_Theatre({
|
||||
Key? key,
|
||||
this.skipCount = 0,
|
||||
this.clipBehavior = Clip.hardEdge,
|
||||
List<Widget> children = const <Widget>[],
|
||||
}) : assert(skipCount != null),
|
||||
assert(skipCount >= 0),
|
||||
assert(children != null),
|
||||
assert(children.length >= skipCount),
|
||||
assert(clipBehavior != null),
|
||||
super(key: key, children: children);
|
||||
|
||||
final int skipCount;
|
||||
|
||||
final Clip clipBehavior;
|
||||
|
||||
@override
|
||||
_TheatreElement createElement() => _TheatreElement(this);
|
||||
|
||||
@@ -507,6 +519,7 @@ class _Theatre extends MultiChildRenderObjectWidget {
|
||||
return _RenderTheatre(
|
||||
skipCount: skipCount,
|
||||
textDirection: Directionality.of(context)!,
|
||||
clipBehavior: clipBehavior,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -514,7 +527,8 @@ class _Theatre extends MultiChildRenderObjectWidget {
|
||||
void updateRenderObject(BuildContext context, _RenderTheatre renderObject) {
|
||||
renderObject
|
||||
..skipCount = skipCount
|
||||
..textDirection = Directionality.of(context)!;
|
||||
..textDirection = Directionality.of(context)!
|
||||
..clipBehavior = clipBehavior;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -545,11 +559,14 @@ class _RenderTheatre extends RenderBox with ContainerRenderObjectMixin<RenderBox
|
||||
List<RenderBox>? children,
|
||||
required TextDirection textDirection,
|
||||
int skipCount = 0,
|
||||
Clip clipBehavior = Clip.hardEdge,
|
||||
}) : assert(skipCount != null),
|
||||
assert(skipCount >= 0),
|
||||
assert(textDirection != null),
|
||||
assert(clipBehavior != null),
|
||||
_textDirection = textDirection,
|
||||
_skipCount = skipCount {
|
||||
_skipCount = skipCount,
|
||||
_clipBehavior = clipBehavior {
|
||||
addAll(children);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
if (skipCount == super.childCount) {
|
||||
return null;
|
||||
@@ -724,8 +755,8 @@ class _RenderTheatre extends RenderBox with ContainerRenderObjectMixin<RenderBox
|
||||
|
||||
@override
|
||||
void paint(PaintingContext context, Offset offset) {
|
||||
if (_hasVisualOverflow) {
|
||||
context.pushClipRect(needsCompositing, offset, Offset.zero & size, paintStack);
|
||||
if (_hasVisualOverflow && clipBehavior != Clip.none) {
|
||||
context.pushClipRect(needsCompositing, offset, Offset.zero & size, paintStack, clipBehavior: clipBehavior);
|
||||
} else {
|
||||
paintStack(context, offset);
|
||||
}
|
||||
|
||||
@@ -71,9 +71,11 @@ class AndroidView extends StatefulWidget {
|
||||
this.gestureRecognizers,
|
||||
this.creationParams,
|
||||
this.creationParamsCodec,
|
||||
this.clipBehavior = Clip.hardEdge,
|
||||
}) : assert(viewType != null),
|
||||
assert(hitTestBehavior != null),
|
||||
assert(creationParams == null || creationParamsCodec != null),
|
||||
assert(clipBehavior != null),
|
||||
super(key: key);
|
||||
|
||||
/// The unique identifier for Android view type to be embedded by this widget.
|
||||
@@ -181,6 +183,11 @@ class AndroidView extends StatefulWidget {
|
||||
/// This must not be null if [creationParams] is not null.
|
||||
final MessageCodec<dynamic>? creationParamsCodec;
|
||||
|
||||
/// {@macro flutter.widgets.Clip}
|
||||
///
|
||||
/// Defaults to [Clip.hardEdge], and must not be null.
|
||||
final Clip clipBehavior;
|
||||
|
||||
@override
|
||||
State<AndroidView> createState() => _AndroidViewState();
|
||||
}
|
||||
@@ -434,6 +441,7 @@ class _AndroidViewState extends State<AndroidView> {
|
||||
controller: _controller,
|
||||
hitTestBehavior: widget.hitTestBehavior,
|
||||
gestureRecognizers: widget.gestureRecognizers ?? _emptyRecognizersSet,
|
||||
clipBehavior: widget.clipBehavior,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -643,14 +651,17 @@ class _AndroidPlatformView extends LeafRenderObjectWidget {
|
||||
required this.controller,
|
||||
required this.hitTestBehavior,
|
||||
required this.gestureRecognizers,
|
||||
this.clipBehavior = Clip.hardEdge,
|
||||
}) : assert(controller != null),
|
||||
assert(hitTestBehavior != null),
|
||||
assert(gestureRecognizers != null),
|
||||
assert(clipBehavior != null),
|
||||
super(key: key);
|
||||
|
||||
final AndroidViewController controller;
|
||||
final PlatformViewHitTestBehavior hitTestBehavior;
|
||||
final Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers;
|
||||
final Clip clipBehavior;
|
||||
|
||||
@override
|
||||
RenderObject createRenderObject(BuildContext context) =>
|
||||
@@ -658,6 +669,7 @@ class _AndroidPlatformView extends LeafRenderObjectWidget {
|
||||
viewController: controller,
|
||||
hitTestBehavior: hitTestBehavior,
|
||||
gestureRecognizers: gestureRecognizers,
|
||||
clipBehavior: clipBehavior,
|
||||
);
|
||||
|
||||
@override
|
||||
@@ -665,6 +677,7 @@ class _AndroidPlatformView extends LeafRenderObjectWidget {
|
||||
renderObject.viewController = controller;
|
||||
renderObject.hitTestBehavior = hitTestBehavior;
|
||||
renderObject.updateGestureRecognizers(gestureRecognizers);
|
||||
renderObject.clipBehavior = clipBehavior;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -281,5 +281,41 @@ void main() {
|
||||
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() {
|
||||
expect(opacityLayer.alpha, equals(opacity * 255));
|
||||
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() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Can used Positioned within OverlayEntry', (WidgetTester tester) async {
|
||||
testWidgets('Can use Positioned within OverlayEntry', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@@ -1024,6 +1024,42 @@ void main() {
|
||||
|
||||
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 {
|
||||
|
||||
@@ -1103,6 +1103,52 @@ void main() {
|
||||
|
||||
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', () {
|
||||
|
||||
Reference in New Issue
Block a user