-
Notifications
You must be signed in to change notification settings - Fork 26.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
When there is a RouteObserver set inside the child of a Hero widget, Flutter crashes #29538
Comments
cc @goderbauer |
I was able to reproduce the issue here. The issue is because of Since your While to avoid the error, you can simply check if the @override
void didChangeDependencies() {
super.didChangeDependencies();
dynamic route = ModalRoute.of(context);
if (route != null) {
widget.routeObserver.subscribe(this, route);
}
} Edit: |
Issue replicable on latest stable (1.20.2). log
|
Reproducible on latest stable and the master channel. code sampleimport 'package:flutter/material.dart';
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'HERO and RouteObserver'),
routes: <String, WidgetBuilder> {
'test': (BuildContext context) => TestPage(
routeObserver: routeObserver
)
},
navigatorObservers: [routeObserver],
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key,required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blue,
appBar: AppBar(
title: Text(widget.title),
),
body: Hero(
tag: "HeroTag",
child: TestWidget(
routeObserver: routeObserver
),
),
floatingActionButton: FloatingActionButton(
onPressed: _toTestPage,
child: Icon(Icons.add),
),
);
}
void _toTestPage() {
Navigator.of(context).pushNamed("test");
}
}
class TestPage extends StatefulWidget {
const TestPage({
required this.routeObserver
});
final RouteObserver<PageRoute> routeObserver;
@override
State<StatefulWidget> createState() => TestPageState();
}
class TestPageState extends State<TestPage> with RouteAware {
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
widget.routeObserver.subscribe(this, ModalRoute.of(context) as PageRoute);
}
@override
void didPush() {
print("did push: test_page");
}
@override
void didPushNext() {
print("did push next: test_page");
}
@override
void didPop() {
print("did pop: test_page");
}
@override
void didPopNext() {
print("did pop next: test_page");
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blue,
appBar: AppBar(
title: Text("Test Page"),
),
body: Center(
child: Container(
width: 200,
height: 200,
child: Hero(
tag: "HeroTag",
child: TestWidget(
routeObserver: widget.routeObserver
),
),
),
),
);
}
}
class TestWidget extends StatefulWidget {
const TestWidget({
required this.routeObserver
});
final RouteObserver<PageRoute> routeObserver;
@override
State<StatefulWidget> createState() => TestWidgetState();
}
class TestWidgetState extends State<TestWidget> with RouteAware {
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
widget.routeObserver.subscribe(this, ModalRoute.of(context) as PageRoute);
}
@override
void didPush() {
print("did push: test_widget");
}
@override
void didPushNext() {
print("did push next: test_widget");
}
@override
void didPop() {
print("did pop: test_widget");
}
@override
void didPopNext() {
print("did pop next: test_widget");
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
child : Center(
child: Text("Hero"),
)
);
}
} logsLaunching lib/main.dart on iPhone 12 Pro in debug mode...
Xcode build done. 10.1s
Connecting to VM Service at ws://127.0.0.1:60705/2-uKaUY6b-w=/ws
flutter: did push: test_widget
flutter: did push next: test_widget
flutter: did push: test_page
flutter: did push: test_widget
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following _CastError was thrown building MediaQuery(MediaQueryData(size: Size(390.0, 844.0),
devicePixelRatio: 3.0, textScaleFactor: 1.0, platformBrightness: Brightness.light, padding:
EdgeInsets(0.0, 0.0, 0.0, 34.0), viewPadding: EdgeInsets(0.0, 0.0, 0.0, 34.0), viewInsets:
EdgeInsets.zero, alwaysUse24HourFormat: false, accessibleNavigation: false, highContrast: false,
disableAnimations: false, invertColors: false, boldText: false, navigationMode: traditional,
gestureSettings: DeviceGestureSettings(touchSlop: null), displayFeatures: [])):
type 'Null' is not a subtype of type 'PageRoute<dynamic>' in type cast
The relevant error-causing widget was:
MaterialApp MaterialApp:file:///Users/mahesh/Desktop/flutter_issue/lib/main.dart:10:12
When the exception was thrown, this was the stack:
#0 TestWidgetState.didChangeDependencies (package:flutter_issue/main.dart:158:65)
#1 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5119:11)
#2 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4944:5)
... Normal element mounting (57 frames)
#59 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3953:16)
#60 MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6512:36)
#61 Element.updateChild (package:flutter/src/widgets/framework.dart:3682:18)
#62 RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:6041:32)
#63 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6537:17)
#64 Element.updateChild (package:flutter/src/widgets/framework.dart:3660:15)
#65 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4993:16)
#66 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5133:11)
#67 Element.rebuild (package:flutter/src/widgets/framework.dart:4690:5)
#68 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2743:19)
#69 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:867:21)
#70 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:381:5)
#71 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1289:15)
#72 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1218:9)
#73 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1076:5)
#74 _invoke (dart:ui/hooks.dart:145:13)
#75 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:338:5)
#76 _drawFrame (dart:ui/hooks.dart:112:31)
════════════════════════════════════════════════════════════════════════════════════════════════════
flutter: did push: test_widget
flutter doctor -v (mac)
|
If you take out only the Hero widget from the below code, everything works as expected.
Code
Logs
The text was updated successfully, but these errors were encountered: