V1.9.1 hotfix (#43288)
This fixes the issue described in https://github.com/flutter/flutter/issues/40239:
* Restore offstage and ticker mode after hero pop and the from hero is null (#40306)
diff --git a/packages/flutter/lib/src/widgets/heroes.dart b/packages/flutter/lib/src/widgets/heroes.dart
index a4299df..eb84423 100644
--- a/packages/flutter/lib/src/widgets/heroes.dart
+++ b/packages/flutter/lib/src/widgets/heroes.dart
@@ -359,7 +359,8 @@
}
// When `keepPlaceholder` is true, the placeholder will continue to be shown
- // after the flight ends.
+ // after the flight ends. Otherwise the child of the Hero will become visible
+ // and its TickerMode will be re-enabled.
void endFlight({ bool keepPlaceholder = false }) {
if (!keepPlaceholder) {
ensurePlaceholderIsHidden();
@@ -828,6 +829,13 @@
_flights[tag].abort();
}
}
+
+ // If the from hero is gone, the flight won't start and the to hero needs to
+ // be put on stage again.
+ for (Object tag in toHeroes.keys) {
+ if (fromHeroes[tag] == null)
+ toHeroes[tag].ensurePlaceholderIsHidden();
+ }
}
void _handleFlightEnded(_HeroFlight flight) {
diff --git a/packages/flutter/test/widgets/heroes_test.dart b/packages/flutter/test/widgets/heroes_test.dart
index 42390ed..0a013ac 100644
--- a/packages/flutter/test/widgets/heroes_test.dart
+++ b/packages/flutter/test/widgets/heroes_test.dart
@@ -2255,4 +2255,54 @@
moreOrLessEquals(tester.getTopLeft(find.text('1')).dx, epsilon: 0.01)
);
});
+
+ // Regression test for https://github.com/flutter/flutter/issues/40239.
+ testWidgets(
+ 'In a pop transition, when fromHero is null, the to hero should eventually become visible',
+ (WidgetTester tester) async {
+ final GlobalKey<NavigatorState> navigatorKey = GlobalKey();
+ StateSetter setState;
+ bool shouldDisplayHero = true;
+ await tester.pumpWidget(
+ CupertinoApp(
+ navigatorKey: navigatorKey,
+ home: Hero(
+ tag: navigatorKey,
+ child: const Placeholder(),
+ ),
+ ),
+ );
+
+ final CupertinoPageRoute<void> route2 = CupertinoPageRoute<void>(
+ builder: (BuildContext context) {
+ return CupertinoPageScaffold(
+ child: StatefulBuilder(
+ builder: (BuildContext context, StateSetter setter) {
+ setState = setter;
+ return shouldDisplayHero
+ ? Hero(tag: navigatorKey, child: const Text('text'))
+ : const SizedBox();
+ },
+ ),
+ );
+ },
+ );
+
+ navigatorKey.currentState.push(route2);
+ await tester.pumpAndSettle();
+
+ expect(find.text('text'), findsOneWidget);
+ expect(find.byType(Placeholder), findsNothing);
+
+ setState(() { shouldDisplayHero = false; });
+ await tester.pumpAndSettle();
+
+ expect(find.text('text'), findsNothing);
+
+ navigatorKey.currentState.pop();
+ await tester.pumpAndSettle();
+
+ expect(find.byType(Placeholder), findsOneWidget);
+ },
+ );
}