Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
9ae37030
Unverified
Commit
9ae37030
authored
Jul 22, 2022
by
Jonah Williams
Committed by
GitHub
Jul 22, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use toPictureSync for faster zoom page transition (#106621)
parent
9f7033a9
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1487 additions
and
86 deletions
+1487
-86
route.dart
packages/flutter/lib/src/cupertino/route.dart
+7
-1
page.dart
packages/flutter/lib/src/material/page.dart
+7
-1
page_transitions_theme.dart
...ages/flutter/lib/src/material/page_transitions_theme.dart
+338
-45
layer.dart
packages/flutter/lib/src/rendering/layer.dart
+81
-11
pages.dart
packages/flutter/lib/src/widgets/pages.dart
+5
-0
raster_widget.dart
packages/flutter/lib/src/widgets/raster_widget.dart
+458
-0
routes.dart
packages/flutter/lib/src/widgets/routes.dart
+18
-0
widgets.dart
packages/flutter/lib/widgets.dart
+1
-0
page_test.dart
packages/flutter/test/material/page_test.dart
+31
-26
text_field_test.dart
packages/flutter/test/material/text_field_test.dart
+1
-1
layers_test.dart
packages/flutter/test/rendering/layers_test.dart
+47
-0
navigator_test.dart
packages/flutter/test/widgets/navigator_test.dart
+1
-1
raster_widget_test.dart
packages/flutter/test/widgets/raster_widget_test.dart
+477
-0
controller.dart
packages/flutter_test/lib/src/controller.dart
+15
-0
No files found.
packages/flutter/lib/src/cupertino/route.dart
View file @
9ae37030
...
...
@@ -342,6 +342,7 @@ class CupertinoPageRoute<T> extends PageRoute<T> with CupertinoRouteTransitionMi
super
.
settings
,
this
.
maintainState
=
true
,
super
.
fullscreenDialog
,
super
.
preferRasterization
=
true
,
})
:
assert
(
builder
!=
null
),
assert
(
maintainState
!=
null
),
assert
(
fullscreenDialog
!=
null
)
{
...
...
@@ -371,6 +372,7 @@ class CupertinoPageRoute<T> extends PageRoute<T> with CupertinoRouteTransitionMi
class
_PageBasedCupertinoPageRoute
<
T
>
extends
PageRoute
<
T
>
with
CupertinoRouteTransitionMixin
<
T
>
{
_PageBasedCupertinoPageRoute
({
required
CupertinoPage
<
T
>
page
,
super
.
preferRasterization
=
true
,
})
:
assert
(
page
!=
null
),
super
(
settings:
page
)
{
assert
(
opaque
);
...
...
@@ -417,6 +419,7 @@ class CupertinoPage<T> extends Page<T> {
this
.
maintainState
=
true
,
this
.
title
,
this
.
fullscreenDialog
=
false
,
this
.
preferRasterization
=
true
,
super
.
key
,
super
.
name
,
super
.
arguments
,
...
...
@@ -437,9 +440,12 @@ class CupertinoPage<T> extends Page<T> {
/// {@macro flutter.widgets.PageRoute.fullscreenDialog}
final
bool
fullscreenDialog
;
/// {@macro flutter.widgets.TransitionRoute.preferRasterization}
final
bool
preferRasterization
;
@override
Route
<
T
>
createRoute
(
BuildContext
context
)
{
return
_PageBasedCupertinoPageRoute
<
T
>(
page:
this
);
return
_PageBasedCupertinoPageRoute
<
T
>(
page:
this
,
preferRasterization:
preferRasterization
);
}
}
...
...
packages/flutter/lib/src/material/page.dart
View file @
9ae37030
...
...
@@ -39,6 +39,7 @@ class MaterialPageRoute<T> extends PageRoute<T> with MaterialRouteTransitionMixi
super
.
settings
,
this
.
maintainState
=
true
,
super
.
fullscreenDialog
,
super
.
preferRasterization
=
true
,
})
:
assert
(
builder
!=
null
),
assert
(
maintainState
!=
null
),
assert
(
fullscreenDialog
!=
null
)
{
...
...
@@ -157,6 +158,7 @@ class MaterialPage<T> extends Page<T> {
required
this
.
child
,
this
.
maintainState
=
true
,
this
.
fullscreenDialog
=
false
,
this
.
preferRasterization
=
true
,
super
.
key
,
super
.
name
,
super
.
arguments
,
...
...
@@ -174,9 +176,12 @@ class MaterialPage<T> extends Page<T> {
/// {@macro flutter.widgets.PageRoute.fullscreenDialog}
final
bool
fullscreenDialog
;
/// {@macro flutter.widgets.TransitionRoute.preferRasterization}
final
bool
preferRasterization
;
@override
Route
<
T
>
createRoute
(
BuildContext
context
)
{
return
_PageBasedMaterialPageRoute
<
T
>(
page:
this
);
return
_PageBasedMaterialPageRoute
<
T
>(
page:
this
,
preferRasterization:
preferRasterization
);
}
}
...
...
@@ -187,6 +192,7 @@ class MaterialPage<T> extends Page<T> {
class
_PageBasedMaterialPageRoute
<
T
>
extends
PageRoute
<
T
>
with
MaterialRouteTransitionMixin
<
T
>
{
_PageBasedMaterialPageRoute
({
required
MaterialPage
<
T
>
page
,
super
.
preferRasterization
,
})
:
assert
(
page
!=
null
),
super
(
settings:
page
)
{
assert
(
opaque
);
...
...
packages/flutter/lib/src/material/page_transitions_theme.dart
View file @
9ae37030
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/rendering/layer.dart
View file @
9ae37030
...
...
@@ -168,6 +168,18 @@ abstract class Layer extends AbstractNode with DiagnosticableTreeMixin {
bool
_debugMutationsLocked
=
false
;
/// Whether or not this layer, or any child layers, can be rasterized with
/// [Scene.toImage] or [Scene.toImageSync].
///
/// If `false`, calling the above methods may yield an image which is
/// incomplete.
///
/// This value may change throughout the lifetime of the object, as the
/// child layers themselves are added or removed.
bool
supportsRasterization
()
{
return
true
;
}
/// Describes the clip that would be applied to contents of this layer,
/// if any.
Rect
?
describeClipBounds
()
=>
null
;
...
...
@@ -875,6 +887,12 @@ class TextureLayer extends Layer {
/// The identity of the backend texture.
final
int
textureId
;
// TODO(jonahwilliams): remove once https://github.com/flutter/flutter/issues/107576 is fixed.
@override
bool
supportsRasterization
()
{
return
false
;
}
/// When true the texture will not be updated with new frames.
///
/// This is used for resizing embedded Android views: when resizing there
...
...
@@ -925,6 +943,11 @@ class PlatformViewLayer extends Layer {
/// A UIView with this identifier must have been created by [PlatformViewsService.initUiKitView].
final
int
viewId
;
@override
bool
supportsRasterization
()
{
return
false
;
}
@override
void
addToScene
(
ui
.
SceneBuilder
builder
)
{
builder
.
addPlatformView
(
...
...
@@ -1043,6 +1066,16 @@ class ContainerLayer extends Layer {
/// Returns whether this layer has at least one child layer.
bool
get
hasChildren
=>
_firstChild
!=
null
;
@override
bool
supportsRasterization
()
{
for
(
Layer
?
child
=
lastChild
;
child
!=
null
;
child
=
child
.
previousSibling
)
{
if
(!
child
.
supportsRasterization
())
{
return
false
;
}
}
return
true
;
}
/// Consider this layer as the root and build a scene (a tree of layers)
/// in the engine.
// The reason this method is in the `ContainerLayer` class rather than
...
...
@@ -1385,6 +1418,16 @@ class OffsetLayer extends ContainerLayer {
properties
.
add
(
DiagnosticsProperty
<
Offset
>(
'offset'
,
offset
));
}
ui
.
Scene
_createSceneForImage
(
Rect
bounds
,
{
double
pixelRatio
=
1.0
})
{
assert
(
bounds
!=
null
);
assert
(
pixelRatio
!=
null
);
final
ui
.
SceneBuilder
builder
=
ui
.
SceneBuilder
();
final
Matrix4
transform
=
Matrix4
.
diagonal3Values
(
pixelRatio
,
pixelRatio
,
1
);
transform
.
translate
(-(
bounds
.
left
+
offset
.
dx
),
-(
bounds
.
top
+
offset
.
dy
));
builder
.
pushTransform
(
transform
.
storage
);
return
buildScene
(
builder
);
}
/// Capture an image of the current state of this layer and its children.
///
/// The returned [ui.Image] has uncompressed raw RGBA bytes, will be offset
...
...
@@ -1397,22 +1440,15 @@ class OffsetLayer extends ContainerLayer {
/// (the default) will give you a 1:1 mapping between logical pixels and the
/// output pixels in the image.
///
/// This API functions like [toImageSync], except that it only returns after
/// rasterization is complete.
///
/// See also:
///
/// * [RenderRepaintBoundary.toImage] for a similar API at the render object level.
/// * [dart:ui.Scene.toImage] for more information about the image returned.
Future
<
ui
.
Image
>
toImage
(
Rect
bounds
,
{
double
pixelRatio
=
1.0
})
async
{
assert
(
bounds
!=
null
);
assert
(
pixelRatio
!=
null
);
final
ui
.
SceneBuilder
builder
=
ui
.
SceneBuilder
();
final
Matrix4
transform
=
Matrix4
.
translationValues
(
(-
bounds
.
left
-
offset
.
dx
)
*
pixelRatio
,
(-
bounds
.
top
-
offset
.
dy
)
*
pixelRatio
,
0.0
,
);
transform
.
scale
(
pixelRatio
,
pixelRatio
);
builder
.
pushTransform
(
transform
.
storage
);
final
ui
.
Scene
scene
=
buildScene
(
builder
);
final
ui
.
Scene
scene
=
_createSceneForImage
(
bounds
,
pixelRatio:
pixelRatio
);
try
{
// Size is rounded up to the next pixel to make sure we don't clip off
...
...
@@ -1425,6 +1461,40 @@ class OffsetLayer extends ContainerLayer {
scene
.
dispose
();
}
}
/// Capture an image of the current state of this layer and its children.
///
/// The returned [ui.Image] has uncompressed raw RGBA bytes, will be offset
/// by the top-left corner of [bounds], and have dimensions equal to the size
/// of [bounds] multiplied by [pixelRatio].
///
/// The [pixelRatio] describes the scale between the logical pixels and the
/// size of the output image. It is independent of the
/// [dart:ui.FlutterView.devicePixelRatio] for the device, so specifying 1.0
/// (the default) will give you a 1:1 mapping between logical pixels and the
/// output pixels in the image.
///
/// This API functions like [toImage], except that rasterization begins eagerly
/// on the raster thread and the image is returned before this is completed.
///
/// See also:
///
/// * [RenderRepaintBoundary.toImage] for a similar API at the render object level.
/// * [dart:ui.Scene.toImage] for more information about the image returned.
ui
.
Image
toImageSync
(
Rect
bounds
,
{
double
pixelRatio
=
1.0
})
{
final
ui
.
Scene
scene
=
_createSceneForImage
(
bounds
,
pixelRatio:
pixelRatio
);
try
{
// Size is rounded up to the next pixel to make sure we don't clip off
// anything.
return
scene
.
toImageSync
(
(
pixelRatio
*
bounds
.
width
).
ceil
(),
(
pixelRatio
*
bounds
.
height
).
ceil
(),
);
}
finally
{
scene
.
dispose
();
}
}
}
/// A composite layer that clips its children using a rectangle.
...
...
packages/flutter/lib/src/widgets/pages.dart
View file @
9ae37030
...
...
@@ -12,6 +12,7 @@ abstract class PageRoute<T> extends ModalRoute<T> {
PageRoute
({
super
.
settings
,
this
.
fullscreenDialog
=
false
,
this
.
preferRasterization
=
true
,
});
/// {@template flutter.widgets.PageRoute.fullscreenDialog}
...
...
@@ -24,6 +25,9 @@ abstract class PageRoute<T> extends ModalRoute<T> {
/// {@endtemplate}
final
bool
fullscreenDialog
;
@override
final
bool
preferRasterization
;
@override
bool
get
opaque
=>
true
;
...
...
@@ -62,6 +66,7 @@ class PageRouteBuilder<T> extends PageRoute<T> {
this
.
barrierLabel
,
this
.
maintainState
=
true
,
super
.
fullscreenDialog
,
super
.
preferRasterization
=
true
,
})
:
assert
(
pageBuilder
!=
null
),
assert
(
transitionsBuilder
!=
null
),
assert
(
opaque
!=
null
),
...
...
packages/flutter/lib/src/widgets/raster_widget.dart
0 → 100644
View file @
9ae37030
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/widgets/routes.dart
View file @
9ae37030
...
...
@@ -126,6 +126,21 @@ abstract class TransitionRoute<T> extends OverlayRoute<T> {
/// {@endtemplate}
bool
get
opaque
;
/// {@template flutter.widgets.TransitionRoute.preferRasterization}
/// Whether the route transition will prefer to animate a rasterized
/// snapshot of the entering/exiting routes.
///
/// When this value is true, certain route transitions (such as the Android
/// zoom page transition) will rasterize the entering and exiting routes.
/// These textures are then animated in place of the underlying widgets to
/// improve performance of the transition.
///
/// Generally this means that animations that occur on the entering/exiting
/// route while the route animation plays may appear frozen - unless they
/// are a hero animation or something that is drawn in a separate overlay.
/// {@endtemplate}
bool
get
preferRasterization
=>
true
;
// This ensures that if we got to the dismissed state while still current,
// we will still be disposed when we are eventually popped.
//
...
...
@@ -1719,6 +1734,9 @@ abstract class PopupRoute<T> extends ModalRoute<T> {
@override
bool
get
maintainState
=>
true
;
@override
bool
get
preferRasterization
=>
false
;
}
/// A [Navigator] observer that notifies [RouteAware]s of changes to the
...
...
packages/flutter/lib/widgets.dart
View file @
9ae37030
...
...
@@ -89,6 +89,7 @@ export 'src/widgets/platform_menu_bar.dart';
export
'src/widgets/platform_view.dart'
;
export
'src/widgets/preferred_size.dart'
;
export
'src/widgets/primary_scroll_controller.dart'
;
export
'src/widgets/raster_widget.dart'
;
export
'src/widgets/raw_keyboard_listener.dart'
;
export
'src/widgets/reorderable_list.dart'
;
export
'src/widgets/restoration.dart'
;
...
...
packages/flutter/test/material/page_test.dart
View file @
9ae37030
...
...
@@ -155,32 +155,33 @@ void main() {
expect
(
widget1InitialTopLeft
==
widget1TransientTopLeft
,
true
);
},
variant:
const
TargetPlatformVariant
(<
TargetPlatform
>{
TargetPlatform
.
iOS
,
TargetPlatform
.
macOS
}));
testWidgets
(
'test page transition (_ZoomPageTransition)'
,
(
WidgetTester
tester
)
async
{
Iterable
<
T
>
findWidgets
<
T
extends
Widget
>
(
Finder
of
)
{
return
tester
.
widgetList
<
T
>
(
find
.
ancestor
(
of:
of
,
matching:
find
.
byType
(
T
))
,
testWidgets
(
'test page transition (_ZoomPageTransition)
without rasterization
'
,
(
WidgetTester
tester
)
async
{
Iterable
<
Layer
>
findLayers
(
Finder
of
)
{
return
tester
.
layerListOf
(
find
.
ancestor
(
of:
of
,
matching:
find
.
byType
(
RasterWidget
)).
first
,
);
}
FadeTransition
findForwardFadeTransition
(
Finder
of
)
{
return
findWidgets
<
FadeTransition
>(
of
).
where
(
(
FadeTransition
t
)
=>
t
.
opacity
.
status
==
AnimationStatus
.
forward
,
).
first
;
OpacityLayer
findForwardFadeTransition
(
Finder
of
)
{
return
findLayers
(
of
).
whereType
<
OpacityLayer
>().
first
;
}
ScaleTransition
findForwardScaleTransition
(
Finder
of
)
{
return
findWidgets
<
ScaleTransition
>(
of
).
where
(
(
ScaleTransition
t
)
=>
t
.
scale
.
status
==
AnimationStatus
.
forward
,
).
first
;
TransformLayer
findForwardScaleTransition
(
Finder
of
)
{
return
findLayers
(
of
).
whereType
<
TransformLayer
>().
first
;
}
await
tester
.
pumpWidget
(
MaterialApp
(
home:
const
Material
(
child:
Text
(
'Page 1'
)),
routes:
<
String
,
WidgetBuilder
>{
'/next'
:
(
BuildContext
context
)
{
return
const
Material
(
child:
Text
(
'Page 2'
));
},
onGenerateRoute:
(
RouteSettings
settings
)
{
return
MaterialPageRoute
<
void
>(
preferRasterization:
false
,
builder:
(
BuildContext
context
)
{
if
(
settings
.
name
==
'/'
)
{
return
const
Material
(
child:
Text
(
'Page 1'
));
}
return
const
Material
(
child:
Text
(
'Page 2'
));
},
);
},
),
);
...
...
@@ -189,16 +190,20 @@ void main() {
await
tester
.
pump
();
await
tester
.
pump
(
const
Duration
(
milliseconds:
50
));
ScaleTransition
widget1Scale
=
findForwardScaleTransition
(
find
.
text
(
'Page 1'
));
ScaleTransition
widget2Scale
=
findForwardScaleTransition
(
find
.
text
(
'Page 2'
));
FadeTransition
widget2Opacity
=
findForwardFadeTransition
(
find
.
text
(
'Page 2'
));
TransformLayer
widget1Scale
=
findForwardScaleTransition
(
find
.
text
(
'Page 1'
));
TransformLayer
widget2Scale
=
findForwardScaleTransition
(
find
.
text
(
'Page 2'
));
OpacityLayer
widget2Opacity
=
findForwardFadeTransition
(
find
.
text
(
'Page 2'
));
double
getScale
(
TransformLayer
layer
)
{
return
layer
.
transform
!.
storage
[
0
];
}
// Page 1 is enlarging, starts from 1.0.
expect
(
widget1Scale
.
scale
.
value
,
greaterThan
(
1.0
));
expect
(
getScale
(
widget1Scale
)
,
greaterThan
(
1.0
));
// Page 2 is enlarging from the value less than 1.0.
expect
(
widget2Scale
.
scale
.
value
,
lessThan
(
1.0
));
expect
(
getScale
(
widget2Scale
)
,
lessThan
(
1.0
));
// Page 2 is becoming none transparent.
expect
(
widget2Opacity
.
opacity
.
value
,
lessThan
(
1.0
));
expect
(
widget2Opacity
.
alpha
,
lessThan
(
255
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
250
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
1
));
...
...
@@ -216,11 +221,11 @@ void main() {
widget2Opacity
=
findForwardFadeTransition
(
find
.
text
(
'Page 2'
));
// Page 1 is narrowing down, but still larger than 1.0.
expect
(
widget1Scale
.
scale
.
value
,
greaterThan
(
1.0
));
expect
(
getScale
(
widget1Scale
)
,
greaterThan
(
1.0
));
// Page 2 is smaller than 1.0.
expect
(
widget2Scale
.
scale
.
value
,
lessThan
(
1.0
));
expect
(
getScale
(
widget2Scale
)
,
lessThan
(
1.0
));
// Page 2 is becoming transparent.
expect
(
widget2Opacity
.
opacity
.
value
,
lessThan
(
1.0
));
expect
(
widget2Opacity
.
alpha
,
lessThan
(
255
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
200
));
await
tester
.
pump
(
const
Duration
(
milliseconds:
1
));
...
...
packages/flutter/test/material/text_field_test.dart
View file @
9ae37030
...
...
@@ -1679,7 +1679,7 @@ void main() {
// Wait for context menu to be built.
await
tester
.
pumpAndSettle
();
final
RenderBox
container
=
tester
.
renderObject
(
find
.
descendant
(
of:
find
.
byType
(
FadeTransition
),
of:
find
.
byType
(
RasterWidget
),
matching:
find
.
byType
(
SizedBox
),
).
first
);
expect
(
container
.
size
,
Size
.
zero
);
...
...
packages/flutter/test/rendering/layers_test.dart
View file @
9ae37030
...
...
@@ -553,6 +553,24 @@ void main() {
parent
.
buildScene
(
SceneBuilder
());
},
skip:
isBrowser
);
// TODO(yjbanov): `toImage` doesn't work on the Web: https://github.com/flutter/flutter/issues/49857
test
(
'ContainerLayer.toImageSync can render interior layer'
,
()
{
final
OffsetLayer
parent
=
OffsetLayer
();
final
OffsetLayer
child
=
OffsetLayer
();
final
OffsetLayer
grandChild
=
OffsetLayer
();
child
.
append
(
grandChild
);
parent
.
append
(
child
);
// This renders the layers and generates engine layers.
parent
.
buildScene
(
SceneBuilder
());
// Causes grandChild to pass its engine layer as `oldLayer`
grandChild
.
toImageSync
(
const
Rect
.
fromLTRB
(
0
,
0
,
10
,
10
));
// Ensure we can render the same scene again after rendering an interior
// layer.
parent
.
buildScene
(
SceneBuilder
());
},
skip:
isBrowser
);
// TODO(yjbanov): `toImage` doesn't work on the Web: https://github.com/flutter/flutter/issues/49857
test
(
'PictureLayer does not let you call dispose unless refcount is 0'
,
()
{
PictureLayer
layer
=
PictureLayer
(
Rect
.
zero
);
expect
(
layer
.
debugHandleCount
,
0
);
...
...
@@ -980,6 +998,35 @@ void main() {
root
.
dispose
();
expect
(()
=>
callback
(),
returnsNormally
);
});
test
(
'Layer types that support rasterization'
,
()
{
// Supported.
final
OffsetLayer
offsetLayer
=
OffsetLayer
();
final
OpacityLayer
opacityLayer
=
OpacityLayer
();
final
ClipRectLayer
clipRectLayer
=
ClipRectLayer
();
final
ClipRRectLayer
clipRRectLayer
=
ClipRRectLayer
();
final
ImageFilterLayer
imageFilterLayer
=
ImageFilterLayer
();
final
BackdropFilterLayer
backdropFilterLayer
=
BackdropFilterLayer
();
final
PhysicalModelLayer
physicalModelLayer
=
PhysicalModelLayer
();
final
ColorFilterLayer
colorFilterLayer
=
ColorFilterLayer
();
final
ShaderMaskLayer
shaderMaskLayer
=
ShaderMaskLayer
();
expect
(
offsetLayer
.
supportsRasterization
(),
true
);
expect
(
opacityLayer
.
supportsRasterization
(),
true
);
expect
(
clipRectLayer
.
supportsRasterization
(),
true
);
expect
(
clipRRectLayer
.
supportsRasterization
(),
true
);
expect
(
imageFilterLayer
.
supportsRasterization
(),
true
);
expect
(
backdropFilterLayer
.
supportsRasterization
(),
true
);
expect
(
physicalModelLayer
.
supportsRasterization
(),
true
);
expect
(
colorFilterLayer
.
supportsRasterization
(),
true
);
expect
(
shaderMaskLayer
.
supportsRasterization
(),
true
);
// Unsupported.
final
TextureLayer
textureLayer
=
TextureLayer
(
rect:
Rect
.
zero
,
textureId:
1
);
final
PlatformViewLayer
platformViewLayer
=
PlatformViewLayer
(
rect:
Rect
.
zero
,
viewId:
1
);
expect
(
textureLayer
.
supportsRasterization
(),
false
);
expect
(
platformViewLayer
.
supportsRasterization
(),
false
);
});
}
class
FakeEngineLayer
extends
Fake
implements
EngineLayer
{
...
...
packages/flutter/test/widgets/navigator_test.dart
View file @
9ae37030
...
...
@@ -4089,7 +4089,7 @@ class ZeroDurationPage extends Page<void> {
class
ZeroDurationPageRoute
extends
PageRoute
<
void
>
{
ZeroDurationPageRoute
({
required
ZeroDurationPage
page
})
:
super
(
settings:
page
);
:
super
(
settings:
page
,
preferRasterization:
false
);
@override
Duration
get
transitionDuration
=>
Duration
.
zero
;
...
...
packages/flutter/test/widgets/raster_widget_test.dart
0 → 100644
View file @
9ae37030
This diff is collapsed.
Click to expand it.
packages/flutter_test/lib/src/controller.dart
View file @
9ae37030
...
...
@@ -92,6 +92,21 @@ abstract class WidgetController {
});
}
/// Find all layers that are children of the provided [finder].
///
/// The [finder] must match exactly one element.
Iterable
<
Layer
>
layerListOf
(
Finder
finder
)
{
TestAsyncUtils
.
guardSync
();
final
Element
element
=
finder
.
evaluate
().
single
;
final
RenderObject
object
=
element
.
renderObject
!;
RenderObject
current
=
object
;
while
(
current
.
debugLayer
==
null
)
{
current
=
current
.
parent
!
as
RenderObject
;
}
final
ContainerLayer
layer
=
current
.
debugLayer
!;
return
_walkLayers
(
layer
);
}
/// All elements currently in the widget tree (lazy pre-order traversal).
///
/// The returned iterable is lazy. It does not walk the entire widget tree
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment