[Hero] toHero flightShuttleBuilder overrides fromHero flightShuttleBuilder (#77733)
diff --git a/packages/flutter/lib/src/widgets/heroes.dart b/packages/flutter/lib/src/widgets/heroes.dart index a7f4739..d589fa4 100644 --- a/packages/flutter/lib/src/widgets/heroes.dart +++ b/packages/flutter/lib/src/widgets/heroes.dart
@@ -996,8 +996,8 @@ fromHero: fromHero, toHero: toHero, createRectTween: createRectTween, - shuttleBuilder: fromHero.widget.flightShuttleBuilder - ?? toHero.widget.flightShuttleBuilder + shuttleBuilder: toHero.widget.flightShuttleBuilder + ?? fromHero.widget.flightShuttleBuilder ?? _defaultHeroFlightShuttleBuilder, isUserGestureTransition: isUserGestureTransition, isDiverted: existingFlight != null,
diff --git a/packages/flutter/test/widgets/heroes_test.dart b/packages/flutter/test/widgets/heroes_test.dart index 64d85c2..0442a7e 100644 --- a/packages/flutter/test/widgets/heroes_test.dart +++ b/packages/flutter/test/widgets/heroes_test.dart
@@ -1612,7 +1612,7 @@ expect(tester.getTopLeft(find.byKey(firstKey)).dx, x0); }); - testWidgets('Can override flight shuttle', (WidgetTester tester) async { + testWidgets('Can override flight shuttle in to hero', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp( home: Material( child: ListView( @@ -1656,6 +1656,102 @@ expect(find.text('baz'), findsOneWidget); }); + testWidgets('Can override flight shuttle in from hero', (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + home: Material( + child: ListView( + children: <Widget>[ + Hero( + tag: 'a', + child: const Text('foo'), + flightShuttleBuilder: ( + BuildContext flightContext, + Animation<double> animation, + HeroFlightDirection flightDirection, + BuildContext fromHeroContext, + BuildContext toHeroContext, + ) { return const Text('baz'); }, + ), + Builder(builder: (BuildContext context) { + return TextButton( + child: const Text('two'), + onPressed: () => Navigator.push<void>(context, MaterialPageRoute<void>( + builder: (BuildContext context) { + return const Material( + child: Hero(tag: 'a', child: Text('bar')), + ); + }, + )), + ); + }), + ], + ), + ), + )); + + await tester.tap(find.text('two')); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 10)); + + expect(find.text('foo'), findsNothing); + expect(find.text('bar'), findsNothing); + expect(find.text('baz'), findsOneWidget); + }); + + // Regression test for https://github.com/flutter/flutter/issues/77720. + testWidgets("toHero's shuttle builder over fromHero's shuttle builder", (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + home: Material( + child: ListView( + children: <Widget>[ + Hero( + tag: 'a', + child: const Text('foo'), + flightShuttleBuilder: ( + BuildContext flightContext, + Animation<double> animation, + HeroFlightDirection flightDirection, + BuildContext fromHeroContext, + BuildContext toHeroContext, + ) { return const Text('fromHero text'); }, + ), + Builder(builder: (BuildContext context) { + return TextButton( + child: const Text('two'), + onPressed: () => Navigator.push<void>(context, MaterialPageRoute<void>( + builder: (BuildContext context) { + return Material( + child: Hero( + tag: 'a', + child: const Text('bar'), + flightShuttleBuilder: ( + BuildContext flightContext, + Animation<double> animation, + HeroFlightDirection flightDirection, + BuildContext fromHeroContext, + BuildContext toHeroContext, + ) { return const Text('toHero text'); }, + ), + ); + }, + )), + ); + }), + ], + ), + ), + )); + + await tester.tap(find.text('two')); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 10)); + + expect(find.text('foo'), findsNothing); + expect(find.text('bar'), findsNothing); + expect(find.text('fromHero text'), findsNothing); + expect(find.text('toHero text'), findsOneWidget); + }); + testWidgets('Can override flight launch pads', (WidgetTester tester) async { await tester.pumpWidget(MaterialApp( home: Material(