Unverified Commit 7c76dee7 authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Make heroes fly on pushReplacement (#30228)

parent d4c4f563
......@@ -621,6 +621,15 @@ class HeroController extends NavigatorObserver {
_maybeStartHeroTransition(route, previousRoute, HeroFlightDirection.pop, false);
}
@override
void didReplace({ Route<dynamic> newRoute, Route<dynamic> oldRoute }) {
assert(navigator != null);
if (newRoute?.isCurrent == true) {
// Only run hero animations if the top-most route got replaced.
_maybeStartHeroTransition(oldRoute, newRoute, HeroFlightDirection.push, false);
}
}
@override
void didStartUserGesture(Route<dynamic> route, Route<dynamic> previousRoute) {
assert(navigator != null);
......
......@@ -1692,4 +1692,91 @@ void main() {
expect(tester.takeException(), isAssertionError);
});
testWidgets('Heroes fly on pushReplacement', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/28041.
const String heroTag = 'foo';
final GlobalKey<NavigatorState> navigator = GlobalKey();
final Key smallContainer = UniqueKey();
final Key largeContainer = UniqueKey();
await tester.pumpWidget(
MaterialApp(
navigatorKey: navigator,
home: Center(
child: Card(
child: Hero(
tag: heroTag,
child: Container(
key: largeContainer,
color: Colors.red,
height: 200.0,
width: 200.0,
),
),
),
),
),
);
// The initial setup.
expect(find.byKey(largeContainer), isOnstage);
expect(find.byKey(largeContainer), isInCard);
expect(find.byKey(smallContainer, skipOffstage: false), findsNothing);
navigator.currentState.pushReplacement(
MaterialPageRoute<void>(
builder: (BuildContext context) {
return Center(
child: Card(
child: Hero(
tag: heroTag,
child: Container(
key: smallContainer,
color: Colors.red,
height: 100.0,
width: 100.0,
),
),
),
);
}
),
);
await tester.pump();
// The second route exists offstage.
expect(find.byKey(largeContainer), isOnstage);
expect(find.byKey(largeContainer), isInCard);
expect(find.byKey(smallContainer, skipOffstage: false), isOffstage);
expect(find.byKey(smallContainer, skipOffstage: false), isInCard);
await tester.pump();
// The hero started flying.
expect(find.byKey(largeContainer), findsNothing);
expect(find.byKey(smallContainer), isOnstage);
expect(find.byKey(smallContainer), isNotInCard);
await tester.pump(const Duration(milliseconds: 100));
// The hero is in-flight.
expect(find.byKey(largeContainer), findsNothing);
expect(find.byKey(smallContainer), isOnstage);
expect(find.byKey(smallContainer), isNotInCard);
final Size size = tester.getSize(find.byKey(smallContainer));
expect(size.height, greaterThan(100));
expect(size.width, greaterThan(100));
expect(size.height, lessThan(200));
expect(size.width, lessThan(200));
await tester.pumpAndSettle();
// The transition has ended.
expect(find.byKey(largeContainer), findsNothing);
expect(find.byKey(smallContainer), isOnstage);
expect(find.byKey(smallContainer), isInCard);
expect(tester.getSize(find.byKey(smallContainer)), const Size(100,100));
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment