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
8eecdbe8
Unverified
Commit
8eecdbe8
authored
Jan 22, 2020
by
Michael Goderbauer
Committed by
GitHub
Jan 22, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Do not rebuild Routes when a new opaque Route is pushed on top (#48900)
parent
b530111c
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
702 additions
and
277 deletions
+702
-277
stack.dart
packages/flutter/lib/src/rendering/stack.dart
+58
-44
overlay.dart
packages/flutter/lib/src/widgets/overlay.dart
+278
-169
nav_bar_transition_test.dart
packages/flutter/test/cupertino/nav_bar_transition_test.dart
+2
-5
debug_test.dart
packages/flutter/test/material/debug_test.dart
+2
-2
stepper_test.dart
packages/flutter/test/material/stepper_test.dart
+4
-3
navigator_test.dart
packages/flutter/test/widgets/navigator_test.dart
+44
-0
overlay_test.dart
packages/flutter/test/widgets/overlay_test.dart
+314
-54
No files found.
packages/flutter/lib/src/rendering/stack.dart
View file @
8eecdbe8
...
...
@@ -425,7 +425,8 @@ class RenderStack extends RenderBox
}
}
double
_getIntrinsicDimension
(
double
mainChildSizeGetter
(
RenderBox
child
))
{
/// Helper function for calculating the intrinsics metrics of a Stack.
static
double
getIntrinsicDimension
(
RenderBox
firstChild
,
double
mainChildSizeGetter
(
RenderBox
child
))
{
double
extent
=
0.0
;
RenderBox
child
=
firstChild
;
while
(
child
!=
null
)
{
...
...
@@ -440,22 +441,22 @@ class RenderStack extends RenderBox
@override
double
computeMinIntrinsicWidth
(
double
height
)
{
return
_getIntrinsicDimension
(
(
RenderBox
child
)
=>
child
.
getMinIntrinsicWidth
(
height
));
return
getIntrinsicDimension
(
firstChild
,
(
RenderBox
child
)
=>
child
.
getMinIntrinsicWidth
(
height
));
}
@override
double
computeMaxIntrinsicWidth
(
double
height
)
{
return
_getIntrinsicDimension
(
(
RenderBox
child
)
=>
child
.
getMaxIntrinsicWidth
(
height
));
return
getIntrinsicDimension
(
firstChild
,
(
RenderBox
child
)
=>
child
.
getMaxIntrinsicWidth
(
height
));
}
@override
double
computeMinIntrinsicHeight
(
double
width
)
{
return
_getIntrinsicDimension
(
(
RenderBox
child
)
=>
child
.
getMinIntrinsicHeight
(
width
));
return
getIntrinsicDimension
(
firstChild
,
(
RenderBox
child
)
=>
child
.
getMinIntrinsicHeight
(
width
));
}
@override
double
computeMaxIntrinsicHeight
(
double
width
)
{
return
_getIntrinsicDimension
(
(
RenderBox
child
)
=>
child
.
getMaxIntrinsicHeight
(
width
));
return
getIntrinsicDimension
(
firstChild
,
(
RenderBox
child
)
=>
child
.
getMaxIntrinsicHeight
(
width
));
}
@override
...
...
@@ -463,6 +464,57 @@ class RenderStack extends RenderBox
return
defaultComputeDistanceToHighestActualBaseline
(
baseline
);
}
/// Lays out the positioned `child` according to `alignment` within a Stack of `size`.
///
/// Returns true when the child has visual overflow.
static
bool
layoutPositionedChild
(
RenderBox
child
,
StackParentData
childParentData
,
Size
size
,
Alignment
alignment
)
{
assert
(
childParentData
.
isPositioned
);
assert
(
child
.
parentData
==
childParentData
);
bool
hasVisualOverflow
=
false
;
BoxConstraints
childConstraints
=
const
BoxConstraints
();
if
(
childParentData
.
left
!=
null
&&
childParentData
.
right
!=
null
)
childConstraints
=
childConstraints
.
tighten
(
width:
size
.
width
-
childParentData
.
right
-
childParentData
.
left
);
else
if
(
childParentData
.
width
!=
null
)
childConstraints
=
childConstraints
.
tighten
(
width:
childParentData
.
width
);
if
(
childParentData
.
top
!=
null
&&
childParentData
.
bottom
!=
null
)
childConstraints
=
childConstraints
.
tighten
(
height:
size
.
height
-
childParentData
.
bottom
-
childParentData
.
top
);
else
if
(
childParentData
.
height
!=
null
)
childConstraints
=
childConstraints
.
tighten
(
height:
childParentData
.
height
);
child
.
layout
(
childConstraints
,
parentUsesSize:
true
);
double
x
;
if
(
childParentData
.
left
!=
null
)
{
x
=
childParentData
.
left
;
}
else
if
(
childParentData
.
right
!=
null
)
{
x
=
size
.
width
-
childParentData
.
right
-
child
.
size
.
width
;
}
else
{
x
=
alignment
.
alongOffset
(
size
-
child
.
size
as
Offset
).
dx
;
}
if
(
x
<
0.0
||
x
+
child
.
size
.
width
>
size
.
width
)
hasVisualOverflow
=
true
;
double
y
;
if
(
childParentData
.
top
!=
null
)
{
y
=
childParentData
.
top
;
}
else
if
(
childParentData
.
bottom
!=
null
)
{
y
=
size
.
height
-
childParentData
.
bottom
-
child
.
size
.
height
;
}
else
{
y
=
alignment
.
alongOffset
(
size
-
child
.
size
as
Offset
).
dy
;
}
if
(
y
<
0.0
||
y
+
child
.
size
.
height
>
size
.
height
)
hasVisualOverflow
=
true
;
childParentData
.
offset
=
Offset
(
x
,
y
);
return
hasVisualOverflow
;
}
@override
void
performLayout
()
{
_resolve
();
...
...
@@ -527,45 +579,7 @@ class RenderStack extends RenderBox
if
(!
childParentData
.
isPositioned
)
{
childParentData
.
offset
=
_resolvedAlignment
.
alongOffset
(
size
-
child
.
size
as
Offset
);
}
else
{
BoxConstraints
childConstraints
=
const
BoxConstraints
();
if
(
childParentData
.
left
!=
null
&&
childParentData
.
right
!=
null
)
childConstraints
=
childConstraints
.
tighten
(
width:
size
.
width
-
childParentData
.
right
-
childParentData
.
left
);
else
if
(
childParentData
.
width
!=
null
)
childConstraints
=
childConstraints
.
tighten
(
width:
childParentData
.
width
);
if
(
childParentData
.
top
!=
null
&&
childParentData
.
bottom
!=
null
)
childConstraints
=
childConstraints
.
tighten
(
height:
size
.
height
-
childParentData
.
bottom
-
childParentData
.
top
);
else
if
(
childParentData
.
height
!=
null
)
childConstraints
=
childConstraints
.
tighten
(
height:
childParentData
.
height
);
child
.
layout
(
childConstraints
,
parentUsesSize:
true
);
double
x
;
if
(
childParentData
.
left
!=
null
)
{
x
=
childParentData
.
left
;
}
else
if
(
childParentData
.
right
!=
null
)
{
x
=
size
.
width
-
childParentData
.
right
-
child
.
size
.
width
;
}
else
{
x
=
_resolvedAlignment
.
alongOffset
(
size
-
child
.
size
as
Offset
).
dx
;
}
if
(
x
<
0.0
||
x
+
child
.
size
.
width
>
size
.
width
)
_hasVisualOverflow
=
true
;
double
y
;
if
(
childParentData
.
top
!=
null
)
{
y
=
childParentData
.
top
;
}
else
if
(
childParentData
.
bottom
!=
null
)
{
y
=
size
.
height
-
childParentData
.
bottom
-
child
.
size
.
height
;
}
else
{
y
=
_resolvedAlignment
.
alongOffset
(
size
-
child
.
size
as
Offset
).
dy
;
}
if
(
y
<
0.0
||
y
+
child
.
size
.
height
>
size
.
height
)
_hasVisualOverflow
=
true
;
childParentData
.
offset
=
Offset
(
x
,
y
);
_hasVisualOverflow
=
layoutPositionedChild
(
child
,
childParentData
,
size
,
_resolvedAlignment
)
||
_hasVisualOverflow
;
}
assert
(
child
.
parentData
==
childParentData
);
...
...
packages/flutter/lib/src/widgets/overlay.dart
View file @
8eecdbe8
This diff is collapsed.
Click to expand it.
packages/flutter/test/cupertino/nav_bar_transition_test.dart
View file @
8eecdbe8
...
...
@@ -72,12 +72,9 @@ CupertinoPageScaffold scaffoldForNavBar(Widget navBar) {
}
Finder
flying
(
WidgetTester
tester
,
Finder
finder
)
{
final
RenderObjectWithChildMixin
<
RenderStack
>
theater
=
tester
.
renderObject
(
find
.
byType
(
Overlay
));
final
RenderStack
theaterStack
=
theater
.
child
;
final
ContainerRenderObjectMixin
<
RenderBox
,
StackParentData
>
theater
=
tester
.
renderObject
(
find
.
byType
(
Overlay
));
final
Finder
lastOverlayFinder
=
find
.
byElementPredicate
((
Element
element
)
{
return
element
is
RenderObjectElement
&&
element
.
renderObject
==
theaterStack
.
lastChild
;
return
element
is
RenderObjectElement
&&
element
.
renderObject
==
theater
.
lastChild
;
});
assert
(
...
...
packages/flutter/test/material/debug_test.dart
View file @
8eecdbe8
...
...
@@ -132,8 +132,8 @@ void main() {
' Offstage
\n
'
' _ModalScopeStatus
\n
'
' _ModalScope<dynamic>-[LabeledGlobalKey<_ModalScopeState<dynamic>>#969b7]
\n
'
'
_OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#7a3ae]
\n
'
'
Stack
\n
'
'
TickerMode
\n
'
'
_OverlayEntryWidget-[LabeledGlobalKey<_OverlayEntryWidgetState>#545d0]
\n
'
' _Theatre
\n
'
' Overlay-[LabeledGlobalKey<OverlayState>#31a52]
\n
'
' _FocusMarker
\n
'
...
...
packages/flutter/test/material/stepper_test.dart
View file @
8eecdbe8
...
...
@@ -529,12 +529,13 @@ void main() {
// which will change depending on where the test is run.
expect
(
lines
.
length
,
greaterThan
(
7
));
expect
(
lines
.
take
(
8
).
join
(
'
\n
'
),
lines
.
take
(
9
).
join
(
'
\n
'
),
equalsIgnoringHashCodes
(
'══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞════════════════════════
\n
'
'The following assertion was thrown building Stepper(dirty,
\n
'
'dependencies: [_LocalizationsScope-[GlobalKey#00000]], state:
\n
'
'_StepperState#00000):
\n
'
'dependencies: [TickerMode,
\n
'
'_LocalizationsScope-[GlobalKey#6b31b]], state:
\n
'
'_StepperState#1bf00):
\n
'
'Steppers must not be nested.
\n
'
'The material specification advises that one should avoid
\n
'
'embedding steppers within steppers.
\n
'
...
...
packages/flutter/test/widgets/navigator_test.dart
View file @
8eecdbe8
...
...
@@ -1186,6 +1186,33 @@ void main() {
expect
(
find
.
byKey
(
const
ValueKey
<
String
>(
'/A/B'
)),
findsNothing
);
// popped
expect
(
find
.
byKey
(
const
ValueKey
<
String
>(
'/C'
)),
findsOneWidget
);
});
testWidgets
(
'Pushing opaque Route does not rebuild routes below'
,
(
WidgetTester
tester
)
async
{
// Regression test for https://github.com/flutter/flutter/issues/45797.
final
GlobalKey
<
NavigatorState
>
navigator
=
GlobalKey
<
NavigatorState
>();
final
Key
bottomRoute
=
UniqueKey
();
final
Key
topRoute
=
UniqueKey
();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorKey:
navigator
,
routes:
<
String
,
WidgetBuilder
>{
'/'
:
(
BuildContext
context
)
=>
StatefulTestWidget
(
key:
bottomRoute
),
'/a'
:
(
BuildContext
context
)
=>
StatefulTestWidget
(
key:
topRoute
),
},
),
);
expect
(
tester
.
state
<
StatefulTestState
>(
find
.
byKey
(
bottomRoute
)).
rebuildCount
,
1
);
navigator
.
currentState
.
pushNamed
(
'/a'
);
await
tester
.
pumpAndSettle
();
// Bottom route is offstage and did not rebuild.
expect
(
find
.
byKey
(
bottomRoute
),
findsNothing
);
expect
(
tester
.
state
<
StatefulTestState
>(
find
.
byKey
(
bottomRoute
,
skipOffstage:
false
)).
rebuildCount
,
1
);
expect
(
tester
.
state
<
StatefulTestState
>(
find
.
byKey
(
topRoute
)).
rebuildCount
,
1
);
});
}
class
NoAnimationPageRoute
extends
PageRouteBuilder
<
void
>
{
...
...
@@ -1199,3 +1226,20 @@ class NoAnimationPageRoute extends PageRouteBuilder<void> {
return
super
.
createAnimationController
()..
value
=
1.0
;
}
}
class
StatefulTestWidget
extends
StatefulWidget
{
const
StatefulTestWidget
({
Key
key
})
:
super
(
key:
key
);
@override
State
<
StatefulTestWidget
>
createState
()
=>
StatefulTestState
();
}
class
StatefulTestState
extends
State
<
StatefulTestWidget
>
{
int
rebuildCount
=
0
;
@override
Widget
build
(
BuildContext
context
)
{
rebuildCount
+=
1
;
return
Container
();
}
}
packages/flutter/test/widgets/overlay_test.dart
View file @
8eecdbe8
This diff is collapsed.
Click to expand it.
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