improve error message when herocontroller is shared by multiple navig… (#72904)
This commit is contained in:
parent
867698439f
commit
6f4d84cf97
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user