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
9d16b84b
Commit
9d16b84b
authored
Apr 29, 2019
by
Sander Kersten
Committed by
Michael Goderbauer
Apr 29, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix calculation of hero rectTween when Navigator isn't fullscreen (#29677)
parent
ae574981
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
140 additions
and
8 deletions
+140
-8
heroes.dart
packages/flutter/lib/src/widgets/heroes.dart
+18
-8
heroes_test.dart
packages/flutter/test/widgets/heroes_test.dart
+122
-0
No files found.
packages/flutter/lib/src/widgets/heroes.dart
View file @
9d16b84b
...
...
@@ -53,11 +53,15 @@ enum HeroFlightDirection {
pop
,
}
// The bounding box for context in global coordinates.
Rect
_globalBoundingBoxFor
(
BuildContext
context
)
{
// The bounding box for context in ancestorContext coordinate system, or in the global
// coordinate system when null.
Rect
_boundingBoxFor
(
BuildContext
context
,
[
BuildContext
ancestorContext
])
{
final
RenderBox
box
=
context
.
findRenderObject
();
assert
(
box
!=
null
&&
box
.
hasSize
);
return
MatrixUtils
.
transformRect
(
box
.
getTransformTo
(
null
),
Offset
.
zero
&
box
.
size
);
return
MatrixUtils
.
transformRect
(
box
.
getTransformTo
(
ancestorContext
?.
findRenderObject
()),
Offset
.
zero
&
box
.
size
,
);
}
/// A widget that marks its child as being a candidate for
...
...
@@ -496,8 +500,8 @@ class _HeroFlight {
manifest
.
toHero
.
startFlight
();
heroRectTween
=
_doCreateRectTween
(
_
globalBoundingBoxFor
(
manifest
.
fromHero
.
c
ontext
),
_
globalBoundingBoxFor
(
manifest
.
toHero
.
c
ontext
),
_
boundingBoxFor
(
manifest
.
fromHero
.
context
,
manifest
.
fromRoute
.
subtreeC
ontext
),
_
boundingBoxFor
(
manifest
.
toHero
.
context
,
manifest
.
toRoute
.
subtreeC
ontext
),
);
overlayEntry
=
OverlayEntry
(
builder:
_buildOverlay
);
...
...
@@ -540,7 +544,10 @@ class _HeroFlight {
if
(
manifest
.
fromHero
!=
newManifest
.
toHero
)
{
manifest
.
fromHero
.
endFlight
();
newManifest
.
toHero
.
startFlight
();
heroRectTween
=
_doCreateRectTween
(
heroRectTween
.
end
,
_globalBoundingBoxFor
(
newManifest
.
toHero
.
context
));
heroRectTween
=
_doCreateRectTween
(
heroRectTween
.
end
,
_boundingBoxFor
(
newManifest
.
toHero
.
context
,
newManifest
.
toRoute
.
subtreeContext
),
);
}
else
{
// TODO(hansmuller): Use ReverseTween here per github.com/flutter/flutter/pull/12203.
heroRectTween
=
_doCreateRectTween
(
heroRectTween
.
end
,
heroRectTween
.
begin
);
...
...
@@ -552,7 +559,10 @@ class _HeroFlight {
assert
(
manifest
.
fromHero
!=
newManifest
.
fromHero
);
assert
(
manifest
.
toHero
!=
newManifest
.
toHero
);
heroRectTween
=
_doCreateRectTween
(
heroRectTween
.
evaluate
(
_proxyAnimation
),
_globalBoundingBoxFor
(
newManifest
.
toHero
.
context
));
heroRectTween
=
_doCreateRectTween
(
heroRectTween
.
evaluate
(
_proxyAnimation
),
_boundingBoxFor
(
newManifest
.
toHero
.
context
,
newManifest
.
toRoute
.
subtreeContext
),
);
shuttle
=
null
;
if
(
newManifest
.
type
==
HeroFlightDirection
.
pop
)
...
...
@@ -706,7 +716,7 @@ class HeroController extends NavigatorObserver {
return
;
}
final
Rect
navigatorRect
=
_
globalB
oundingBoxFor
(
navigator
.
context
);
final
Rect
navigatorRect
=
_
b
oundingBoxFor
(
navigator
.
context
);
// At this point the toHeroes may have been built and laid out for the first time.
final
Map
<
Object
,
_HeroState
>
fromHeroes
=
Hero
.
_allHeroesFor
(
from
.
subtreeContext
,
isUserGestureTransition
,
navigator
);
...
...
packages/flutter/test/widgets/heroes_test.dart
View file @
9d16b84b
...
...
@@ -1172,6 +1172,128 @@ void main() {
expect
(
tester
.
getCenter
(
find
.
byKey
(
firstKey
)),
const
Offset
(
50.0
,
50.0
));
});
testWidgets
(
'Hero createRectTween for Navigator that is not full screen'
,
(
WidgetTester
tester
)
async
{
// Regression test for https://github.com/flutter/flutter/issues/25272
RectTween
createRectTween
(
Rect
begin
,
Rect
end
)
{
return
RectTween
(
begin:
begin
,
end:
end
);
}
final
Map
<
String
,
WidgetBuilder
>
createRectTweenHeroRoutes
=
<
String
,
WidgetBuilder
>{
'/'
:
(
BuildContext
context
)
=>
Material
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
<
Widget
>[
Hero
(
tag:
'a'
,
createRectTween:
createRectTween
,
child:
Container
(
height:
100.0
,
width:
100.0
,
key:
firstKey
),
),
FlatButton
(
child:
const
Text
(
'two'
),
onPressed:
()
{
Navigator
.
pushNamed
(
context
,
'/two'
);
},
),
],
),
),
'/two'
:
(
BuildContext
context
)
=>
Material
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
<
Widget
>[
SizedBox
(
height:
200.0
,
child:
FlatButton
(
child:
const
Text
(
'pop'
),
onPressed:
()
{
Navigator
.
pop
(
context
);
},
),
),
Hero
(
tag:
'a'
,
createRectTween:
createRectTween
,
child:
Container
(
height:
200.0
,
width:
100.0
,
key:
secondKey
),
),
],
),
),
};
const
double
leftPadding
=
10.0
;
// MaterialApp and its Navigator are offset from the left
await
tester
.
pumpWidget
(
Padding
(
padding:
const
EdgeInsets
.
only
(
left:
leftPadding
),
child:
MaterialApp
(
routes:
createRectTweenHeroRoutes
),
));
expect
(
tester
.
getCenter
(
find
.
byKey
(
firstKey
)),
const
Offset
(
leftPadding
+
50.0
,
50.0
));
const
double
epsilon
=
0.001
;
const
Duration
duration
=
Duration
(
milliseconds:
300
);
const
Curve
curve
=
Curves
.
fastOutSlowIn
;
final
RectTween
pushRectTween
=
RectTween
(
begin:
Rect
.
fromLTWH
(
leftPadding
,
0.0
,
100.0
,
100.0
),
end:
Rect
.
fromLTWH
(
350.0
+
leftPadding
/
2
,
200.0
,
100.0
,
200.0
),
);
await
tester
.
tap
(
find
.
text
(
'two'
));
await
tester
.
pump
();
// begin navigation
// Verify that the rect of the secondKey Hero transforms as the
// pushRectTween rect for the push /two flight.
await
tester
.
pump
();
expect
(
tester
.
getCenter
(
find
.
byKey
(
secondKey
)),
const
Offset
(
50.0
+
leftPadding
,
50.0
));
await
tester
.
pump
(
duration
*
0.25
);
Rect
actualHeroRect
=
tester
.
getRect
(
find
.
byKey
(
secondKey
));
Rect
predictedHeroRect
=
pushRectTween
.
lerp
(
curve
.
transform
(
0.25
));
expect
(
actualHeroRect
,
within
<
Rect
>(
distance:
epsilon
,
from:
predictedHeroRect
));
await
tester
.
pump
(
duration
*
0.25
);
actualHeroRect
=
tester
.
getRect
(
find
.
byKey
(
secondKey
));
predictedHeroRect
=
pushRectTween
.
lerp
(
curve
.
transform
(
0.5
));
expect
(
actualHeroRect
,
within
<
Rect
>(
distance:
epsilon
,
from:
predictedHeroRect
));
await
tester
.
pump
(
duration
*
0.25
);
actualHeroRect
=
tester
.
getRect
(
find
.
byKey
(
secondKey
));
predictedHeroRect
=
pushRectTween
.
lerp
(
curve
.
transform
(
0.75
));
expect
(
actualHeroRect
,
within
<
Rect
>(
distance:
epsilon
,
from:
predictedHeroRect
));
await
tester
.
pumpAndSettle
();
expect
(
tester
.
getCenter
(
find
.
byKey
(
secondKey
)),
const
Offset
(
400.0
+
leftPadding
/
2
,
300.0
));
// Verify that the rect of the firstKey Hero transforms as the
// pushRectTween rect for the pop /two flight.
await
tester
.
tap
(
find
.
text
(
'pop'
));
await
tester
.
pump
();
// begin navigation
final
RectTween
popRectTween
=
RectTween
(
begin:
Rect
.
fromLTWH
(
350.0
+
leftPadding
/
2
,
200.0
,
100.0
,
200.0
),
end:
Rect
.
fromLTWH
(
leftPadding
,
0.0
,
100.0
,
100.0
),
);
await
tester
.
pump
();
expect
(
tester
.
getCenter
(
find
.
byKey
(
firstKey
)),
const
Offset
(
400.0
+
leftPadding
/
2
,
300.0
));
await
tester
.
pump
(
duration
*
0.25
);
actualHeroRect
=
tester
.
getRect
(
find
.
byKey
(
firstKey
));
predictedHeroRect
=
popRectTween
.
lerp
(
curve
.
flipped
.
transform
(
0.25
));
expect
(
actualHeroRect
,
within
<
Rect
>(
distance:
epsilon
,
from:
predictedHeroRect
));
await
tester
.
pump
(
duration
*
0.25
);
actualHeroRect
=
tester
.
getRect
(
find
.
byKey
(
firstKey
));
predictedHeroRect
=
popRectTween
.
lerp
(
curve
.
flipped
.
transform
(
0.5
));
expect
(
actualHeroRect
,
within
<
Rect
>(
distance:
epsilon
,
from:
predictedHeroRect
));
await
tester
.
pump
(
duration
*
0.25
);
actualHeroRect
=
tester
.
getRect
(
find
.
byKey
(
firstKey
));
predictedHeroRect
=
popRectTween
.
lerp
(
curve
.
flipped
.
transform
(
0.75
));
expect
(
actualHeroRect
,
within
<
Rect
>(
distance:
epsilon
,
from:
predictedHeroRect
));
await
tester
.
pumpAndSettle
();
expect
(
tester
.
getCenter
(
find
.
byKey
(
firstKey
)),
const
Offset
(
50.0
+
leftPadding
,
50.0
));
});
testWidgets
(
'Pop interrupts push, reverses flight'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
routes:
routes
));
await
tester
.
tap
(
find
.
text
(
'twoInset'
));
...
...
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