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
05a80eb8
Unverified
Commit
05a80eb8
authored
Dec 30, 2020
by
LongCatIsLooong
Committed by
GitHub
Dec 30, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle infinite/NaN rects in Hero flights. Less exclamation marks. (#72946)
parent
373ec58d
Changes
2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
428 additions
and
161 deletions
+428
-161
heroes.dart
packages/flutter/lib/src/widgets/heroes.dart
+220
-161
heroes_test.dart
packages/flutter/test/widgets/heroes_test.dart
+208
-0
No files found.
packages/flutter/lib/src/widgets/heroes.dart
View file @
05a80eb8
This diff is collapsed.
Click to expand it.
packages/flutter/test/widgets/heroes_test.dart
View file @
05a80eb8
...
@@ -2780,4 +2780,212 @@ Future<void> main() async {
...
@@ -2780,4 +2780,212 @@ Future<void> main() async {
expect
(
find
.
byKey
(
secondKey
),
isInCard
);
expect
(
find
.
byKey
(
secondKey
),
isInCard
);
expect
(
find
.
byKey
(
secondKey
),
isOnstage
);
expect
(
find
.
byKey
(
secondKey
),
isOnstage
);
});
});
testWidgets
(
'kept alive Hero does not throw when the transition begins'
,
(
WidgetTester
tester
)
async
{
final
GlobalKey
<
NavigatorState
>
navigatorKey
=
GlobalKey
<
NavigatorState
>();
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorKey:
navigatorKey
,
home:
Scaffold
(
body:
ListView
(
addAutomaticKeepAlives:
false
,
addRepaintBoundaries:
false
,
addSemanticIndexes:
false
,
children:
<
Widget
>[
const
KeepAlive
(
keepAlive:
true
,
child:
Hero
(
tag:
'a'
,
child:
Placeholder
(),
),
),
Container
(
height:
1000.0
),
],
),
),
),
);
// Scroll to make the Hero invisible.
await
tester
.
drag
(
find
.
byType
(
ListView
),
const
Offset
(
0.0
,
-
1000.0
));
await
tester
.
pump
();
expect
(
find
.
byType
(
TextField
),
findsNothing
);
navigatorKey
.
currentState
?.
push
(
MaterialPageRoute
<
void
>(
builder:
(
BuildContext
context
)
{
return
const
Scaffold
(
body:
Center
(
child:
Hero
(
tag:
'a'
,
child:
Placeholder
(),
),
),
);
},
),
);
await
tester
.
pumpAndSettle
();
expect
(
tester
.
takeException
(),
isNull
);
// The Hero on the new route should be visible .
expect
(
find
.
byType
(
Placeholder
),
findsOneWidget
);
});
testWidgets
(
'toHero becomes unpaintable after the transition begins'
,
(
WidgetTester
tester
)
async
{
final
GlobalKey
<
NavigatorState
>
navigatorKey
=
GlobalKey
<
NavigatorState
>();
final
ScrollController
controller
=
ScrollController
();
RenderOpacity
?
findRenderOpacity
()
{
AbstractNode
?
parent
=
tester
.
renderObject
(
find
.
byType
(
Placeholder
));
while
(
parent
is
RenderObject
&&
parent
is
!
RenderOpacity
)
{
parent
=
parent
.
parent
;
}
return
parent
is
RenderOpacity
?
parent
:
null
;
}
await
tester
.
pumpWidget
(
MaterialApp
(
navigatorKey:
navigatorKey
,
home:
Scaffold
(
body:
ListView
(
controller:
controller
,
addAutomaticKeepAlives:
false
,
addRepaintBoundaries:
false
,
addSemanticIndexes:
false
,
children:
<
Widget
>[
const
KeepAlive
(
keepAlive:
true
,
child:
Hero
(
tag:
'a'
,
child:
Placeholder
(),
),
),
Container
(
height:
1000.0
),
],
),
),
),
);
navigatorKey
.
currentState
?.
push
(
MaterialPageRoute
<
void
>(
builder:
(
BuildContext
context
)
{
return
const
Scaffold
(
body:
Center
(
child:
Hero
(
tag:
'a'
,
child:
Placeholder
(),
),
),
);
},
),
);
await
tester
.
pump
();
await
tester
.
pumpAndSettle
();
// Pop the new route, and before the animation finishes we scroll the toHero
// to make it unpaintable.
navigatorKey
.
currentState
?.
pop
();
await
tester
.
pump
();
controller
.
jumpTo
(
1000
);
// Starts Hero animation and scroll animation almost simutaneously.
// Scroll to make the Hero invisible.
await
tester
.
pump
();
expect
(
findRenderOpacity
()?.
opacity
,
anyOf
(
isNull
,
1.0
));
// In this frame the Hero animation finds out the toHero is not paintable,
// and starts fading.
await
tester
.
pump
();
await
tester
.
pump
(
const
Duration
(
milliseconds:
100
));
expect
(
findRenderOpacity
()?.
opacity
,
lessThan
(
1.0
));
await
tester
.
pumpAndSettle
();
// The Hero on the new route should be invisible.
expect
(
find
.
byType
(
Placeholder
),
findsNothing
);
});
testWidgets
(
'diverting to a keepalive but unpaintable hero'
,
(
WidgetTester
tester
)
async
{
final
GlobalKey
<
NavigatorState
>
navigatorKey
=
GlobalKey
<
NavigatorState
>();
await
tester
.
pumpWidget
(
CupertinoApp
(
navigatorKey:
navigatorKey
,
home:
CupertinoPageScaffold
(
child:
ListView
(
addAutomaticKeepAlives:
false
,
addRepaintBoundaries:
false
,
addSemanticIndexes:
false
,
children:
<
Widget
>[
const
KeepAlive
(
keepAlive:
true
,
child:
Hero
(
tag:
'a'
,
child:
Placeholder
(),
),
),
Container
(
height:
1000.0
),
],
),
),
),
);
// Scroll to make the Hero invisible.
await
tester
.
drag
(
find
.
byType
(
ListView
),
const
Offset
(
0.0
,
-
1000.0
));
await
tester
.
pump
();
expect
(
find
.
byType
(
Placeholder
),
findsNothing
);
expect
(
find
.
byType
(
Placeholder
,
skipOffstage:
false
),
findsOneWidget
);
navigatorKey
.
currentState
?.
push
(
MaterialPageRoute
<
void
>(
builder:
(
BuildContext
context
)
{
return
const
Scaffold
(
body:
Center
(
child:
Hero
(
tag:
'a'
,
child:
Placeholder
(),
),
),
);
},
),
);
await
tester
.
pumpAndSettle
();
// Yet another route that contains Hero 'a'.
navigatorKey
.
currentState
?.
push
(
MaterialPageRoute
<
void
>(
builder:
(
BuildContext
context
)
{
return
const
Scaffold
(
body:
Center
(
child:
Hero
(
tag:
'a'
,
child:
Placeholder
(),
),
),
);
},
),
);
await
tester
.
pumpAndSettle
();
// Pop both routes.
navigatorKey
.
currentState
?.
pop
();
await
tester
.
pump
();
await
tester
.
pump
(
const
Duration
(
milliseconds:
10
));
navigatorKey
.
currentState
?.
pop
();
await
tester
.
pump
();
await
tester
.
pump
(
const
Duration
(
milliseconds:
10
));
expect
(
find
.
byType
(
Placeholder
),
findsOneWidget
);
await
tester
.
pumpAndSettle
();
expect
(
tester
.
takeException
(),
isNull
);
});
}
}
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