Unverified Commit 6f4d84cf authored by chunhtai's avatar chunhtai Committed by GitHub

improve error message when herocontroller is shared by multiple navig… (#72904)

parent 86769843
......@@ -3425,8 +3425,28 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
ServicesBinding.instance!.addPostFrameCallback((Duration timestamp) {
// We only check if this navigator still owns the hero controller.
if (_heroControllerFromScope == newHeroController) {
assert(_heroControllerFromScope!._navigator == this);
assert(previousOwner._heroControllerFromScope != newHeroController);
final bool hasHeroControllerOwnerShip = _heroControllerFromScope!._navigator == this;
if (!hasHeroControllerOwnerShip ||
previousOwner._heroControllerFromScope == newHeroController) {
final NavigatorState otherOwner = hasHeroControllerOwnerShip
? previousOwner
: _heroControllerFromScope!._navigator!;
FlutterError.reportError(
FlutterErrorDetails(
exception: FlutterError(
'A HeroController can not be shared by multiple Navigators. '
'The Navigators that share the same HeroController are:\n'
'- $this\n'
'- $otherOwner\n'
'Please create a HeroControllerScope for each Navigator or '
'use a HeroControllerScope.none to prevent subtree from '
'receiving a HeroController.'
),
library: 'widget library',
stack: StackTrace.current,
),
);
}
}
});
}
......
......@@ -2489,6 +2489,62 @@ void main() {
expect(tester.takeException(), isAssertionError);
});
testWidgets('hero controller throws has correct error message', (WidgetTester tester) async {
final HeroControllerSpy spy = HeroControllerSpy();
await tester.pumpWidget(
HeroControllerScope(
controller: spy,
child: Directionality(
textDirection: TextDirection.ltr,
child: Stack(
children: <Widget>[
Navigator(
initialRoute: 'navigator1',
onGenerateRoute: (RouteSettings s) {
return MaterialPageRoute<void>(
builder: (BuildContext c) {
return const Placeholder();
},
settings: s,
);
},
),
Navigator(
initialRoute: 'navigator2',
onGenerateRoute: (RouteSettings s) {
return MaterialPageRoute<void>(
builder: (BuildContext c) {
return const Placeholder();
},
settings: s,
);
},
),
],
),
),
),
);
final dynamic exception = tester.takeException();
expect(exception, isFlutterError);
final FlutterError error = exception as FlutterError;
expect(
error.toStringDeep(),
equalsIgnoringHashCodes(
'FlutterError\n'
' A HeroController can not be shared by multiple Navigators. The\n'
' Navigators that share the same HeroController are:\n'
' - NavigatorState#00000(tickers: tracking 1 ticker)\n'
' - NavigatorState#00000(tickers: tracking 1 ticker)\n'
' Please create a HeroControllerScope for each Navigator or use a\n'
' HeroControllerScope.none to prevent subtree from receiving a\n'
' HeroController.\n'
''
),
);
});
group('Page api', (){
Widget buildNavigator({
required List<Page<dynamic>> pages,
......
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