mirror of
https://github.com/flutter/flutter
synced 2024-10-13 03:32:55 +00:00
Support clipBehavior changes in hot reload (#31761)
## Description Make `_RenderCustomClip`'s `clipBehavior` non-final so we can update it during `updateRenderObject`. This will support `clipBehavior` changes in hot reload. ## Related Issues Fixes #30863 ## Tests I added the following tests: * ClipRect updates clipBehavior in updateRenderObject * ClipRRect updates clipBehavior in updateRenderObject * ClipOval updates clipBehavior in updateRenderObject * ClipPath updates clipBehavior in updateRenderObject * PhysicalModel updates clipBehavior in updateRenderObject * PhysicalShape updates clipBehavior in updateRenderObject
This commit is contained in:
parent
eae67f05df
commit
7cab6d5e1c
|
@ -1463,6 +1463,7 @@ class PhysicalModelLayer extends ContainerLayer {
|
|||
Clip get clipBehavior => _clipBehavior;
|
||||
Clip _clipBehavior;
|
||||
set clipBehavior(Clip value) {
|
||||
assert(value != null);
|
||||
if (value != _clipBehavior) {
|
||||
_clipBehavior = value;
|
||||
markNeedsAddToScene();
|
||||
|
|
|
@ -1152,9 +1152,10 @@ abstract class _RenderCustomClip<T> extends RenderProxyBox {
|
|||
_RenderCustomClip({
|
||||
RenderBox child,
|
||||
CustomClipper<T> clipper,
|
||||
this.clipBehavior = Clip.antiAlias,
|
||||
}) : _clipper = clipper,
|
||||
assert(clipBehavior != null),
|
||||
Clip clipBehavior = Clip.antiAlias,
|
||||
}) : assert(clipBehavior != null),
|
||||
_clipper = clipper,
|
||||
_clipBehavior = clipBehavior,
|
||||
super(child);
|
||||
|
||||
/// If non-null, determines which clip to use on the child.
|
||||
|
@ -1198,7 +1199,14 @@ abstract class _RenderCustomClip<T> extends RenderProxyBox {
|
|||
T get _defaultClip;
|
||||
T _clip;
|
||||
|
||||
final Clip clipBehavior;
|
||||
Clip get clipBehavior => _clipBehavior;
|
||||
set clipBehavior(Clip value) {
|
||||
if (value != _clipBehavior) {
|
||||
_clipBehavior = value;
|
||||
markNeedsPaint();
|
||||
}
|
||||
}
|
||||
Clip _clipBehavior;
|
||||
|
||||
@override
|
||||
void performLayout() {
|
||||
|
|
|
@ -594,7 +594,9 @@ class ClipRect extends SingleChildRenderObjectWidget {
|
|||
|
||||
@override
|
||||
void updateRenderObject(BuildContext context, RenderClipRect renderObject) {
|
||||
renderObject.clipper = clipper;
|
||||
renderObject
|
||||
..clipper = clipper
|
||||
..clipBehavior = clipBehavior;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -661,6 +663,7 @@ class ClipRRect extends SingleChildRenderObjectWidget {
|
|||
void updateRenderObject(BuildContext context, RenderClipRRect renderObject) {
|
||||
renderObject
|
||||
..borderRadius = borderRadius
|
||||
..clipBehavior = clipBehavior
|
||||
..clipper = clipper;
|
||||
}
|
||||
|
||||
|
@ -710,7 +713,9 @@ class ClipOval extends SingleChildRenderObjectWidget {
|
|||
|
||||
@override
|
||||
void updateRenderObject(BuildContext context, RenderClipOval renderObject) {
|
||||
renderObject.clipper = clipper;
|
||||
renderObject
|
||||
..clipper = clipper
|
||||
..clipBehavior = clipBehavior;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -796,7 +801,9 @@ class ClipPath extends SingleChildRenderObjectWidget {
|
|||
|
||||
@override
|
||||
void updateRenderObject(BuildContext context, RenderClipPath renderObject) {
|
||||
renderObject.clipper = clipper;
|
||||
renderObject
|
||||
..clipper = clipper
|
||||
..clipBehavior = clipBehavior;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -886,6 +893,7 @@ class PhysicalModel extends SingleChildRenderObjectWidget {
|
|||
void updateRenderObject(BuildContext context, RenderPhysicalModel renderObject) {
|
||||
renderObject
|
||||
..shape = shape
|
||||
..clipBehavior = clipBehavior
|
||||
..borderRadius = borderRadius
|
||||
..elevation = elevation
|
||||
..color = color
|
||||
|
@ -974,6 +982,7 @@ class PhysicalShape extends SingleChildRenderObjectWidget {
|
|||
void updateRenderObject(BuildContext context, RenderPhysicalShape renderObject) {
|
||||
renderObject
|
||||
..clipper = clipper
|
||||
..clipBehavior = clipBehavior
|
||||
..elevation = elevation
|
||||
..color = color
|
||||
..shadowColor = shadowColor;
|
||||
|
|
|
@ -40,7 +40,75 @@ class ValueClipper<T> extends CustomClipper<T> {
|
|||
}
|
||||
}
|
||||
|
||||
class _UpdateCountedClipRect extends ClipRect {
|
||||
_UpdateCountedClipRect({Clip clipBehavior = Clip.antiAlias})
|
||||
: super(clipBehavior: clipBehavior);
|
||||
}
|
||||
|
||||
class _UpdateCountedClipRRect extends ClipRRect {
|
||||
_UpdateCountedClipRRect({Clip clipBehavior = Clip.antiAlias})
|
||||
: super(clipBehavior: clipBehavior, borderRadius: BorderRadius.circular(1.0));
|
||||
}
|
||||
|
||||
class _UpdateCountedClipOval extends ClipOval {
|
||||
_UpdateCountedClipOval({Clip clipBehavior = Clip.antiAlias})
|
||||
: super(clipBehavior: clipBehavior);
|
||||
}
|
||||
|
||||
class _UpdateCountedClipPath extends ClipPath {
|
||||
_UpdateCountedClipPath({Clip clipBehavior = Clip.antiAlias})
|
||||
: super(clipBehavior: clipBehavior);
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('ClipRect updates clipBehavior in updateRenderObject', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(_UpdateCountedClipRect());
|
||||
|
||||
final RenderClipRect renderClip = tester.allRenderObjects.whereType<RenderClipRect>().first;
|
||||
|
||||
expect(renderClip.clipBehavior, equals(Clip.antiAlias));
|
||||
|
||||
await tester.pumpWidget(_UpdateCountedClipRect(clipBehavior: Clip.hardEdge));
|
||||
|
||||
expect(renderClip.clipBehavior, equals(Clip.hardEdge));
|
||||
});
|
||||
|
||||
testWidgets('ClipRRect updates clipBehavior in updateRenderObject', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(_UpdateCountedClipRRect());
|
||||
|
||||
final RenderClipRRect renderClip = tester.allRenderObjects.whereType<RenderClipRRect>().first;
|
||||
|
||||
expect(renderClip.clipBehavior, equals(Clip.antiAlias));
|
||||
|
||||
await tester.pumpWidget(_UpdateCountedClipRRect(clipBehavior: Clip.hardEdge));
|
||||
|
||||
expect(renderClip.clipBehavior, equals(Clip.hardEdge));
|
||||
});
|
||||
|
||||
testWidgets('ClipOval updates clipBehavior in updateRenderObject', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(_UpdateCountedClipOval());
|
||||
|
||||
final RenderClipOval renderClip = tester.allRenderObjects.whereType<RenderClipOval>().first;
|
||||
|
||||
expect(renderClip.clipBehavior, equals(Clip.antiAlias));
|
||||
|
||||
await tester.pumpWidget(_UpdateCountedClipOval(clipBehavior: Clip.hardEdge));
|
||||
|
||||
expect(renderClip.clipBehavior, equals(Clip.hardEdge));
|
||||
});
|
||||
|
||||
testWidgets('ClipPath updates clipBehavior in updateRenderObject', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(_UpdateCountedClipPath());
|
||||
|
||||
final RenderClipPath renderClip = tester.allRenderObjects.whereType<RenderClipPath>().first;
|
||||
|
||||
expect(renderClip.clipBehavior, equals(Clip.antiAlias));
|
||||
|
||||
await tester.pumpWidget(_UpdateCountedClipPath(clipBehavior: Clip.hardEdge));
|
||||
|
||||
expect(renderClip.clipBehavior, equals(Clip.hardEdge));
|
||||
});
|
||||
|
||||
testWidgets('ClipPath', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
ClipPath(
|
||||
|
|
|
@ -10,7 +10,49 @@ import 'package:flutter/rendering.dart';
|
|||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
class _UpdateCountedPhysicalModel extends PhysicalModel {
|
||||
_UpdateCountedPhysicalModel({Clip clipBehavior = Clip.none})
|
||||
: super(clipBehavior: clipBehavior, color: Colors.red);
|
||||
}
|
||||
|
||||
class _UpdateCountedPhysicalShape extends PhysicalShape {
|
||||
_UpdateCountedPhysicalShape({Clip clipBehavior = Clip.none})
|
||||
: super(clipBehavior: clipBehavior, color: Colors.red, clipper: ShapeBorderClipper(shape: CircleBorder()));
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('PhysicalModel updates clipBehavior in updateRenderObject', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(home: _UpdateCountedPhysicalModel()),
|
||||
);
|
||||
|
||||
final RenderPhysicalModel renderPhysicalModel = tester.allRenderObjects.whereType<RenderPhysicalModel>().first;
|
||||
|
||||
expect(renderPhysicalModel.clipBehavior, equals(Clip.none));
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(home: _UpdateCountedPhysicalModel(clipBehavior: Clip.antiAlias)),
|
||||
);
|
||||
|
||||
expect(renderPhysicalModel.clipBehavior, equals(Clip.antiAlias));
|
||||
});
|
||||
|
||||
testWidgets('PhysicalShape updates clipBehavior in updateRenderObject', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(home: _UpdateCountedPhysicalShape()),
|
||||
);
|
||||
|
||||
final RenderPhysicalShape renderPhysicalShape = tester.allRenderObjects.whereType<RenderPhysicalShape>().first;
|
||||
|
||||
expect(renderPhysicalShape.clipBehavior, equals(Clip.none));
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(home: _UpdateCountedPhysicalShape(clipBehavior: Clip.antiAlias)),
|
||||
);
|
||||
|
||||
expect(renderPhysicalShape.clipBehavior, equals(Clip.antiAlias));
|
||||
});
|
||||
|
||||
testWidgets('PhysicalModel - creates a physical model layer when it needs compositing', (WidgetTester tester) async {
|
||||
debugDisableShadows = false;
|
||||
await tester.pumpWidget(
|
||||
|
|
Loading…
Reference in a new issue