I am new to Flutter and I am trying to build an app. Which will have multiple pages. When ever I am trying to navigate to second screen it giving me exception. I saw many videos on how to navigate to different pages and did the same thing in my code but this is giving me the expection.
Can anyone please help me? How to resolve this exception? and Why this exception is coming?
main.dart file
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp>{
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Please select your language',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold
),
),
const Text (
'You can change the language at any time',
style: TextStyle(
fontSize: 16,
color: Color.fromRGBO(106, 108, 123, 100)
),
),
DropdownButton<String>(
items: <String>['English', 'Hindi', 'Marathi', 'Punjabi'].map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (_) {},
value: 'English',
),
ElevatedButton(
onPressed: (){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MobileNumber()//Exception on this line.
)
);
},
child: const Text("NEXT"),
)
],
),
)
)
);
}
}
MobileNumber.dart
import 'package:flutter/material.dart';
class MobileNumber extends StatelessWidget{
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: Text("Mobile Number Page"),
),
);
}
}
Exception Stack
======== Exception caught by gesture ===============================================================
The following assertion was thrown while handling a gesture:
Navigator operation requested with a context that does not include a Navigator.
The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.
When the exception was thrown, this was the stack:
#0 Navigator.of.<anonymous closure> (package:flutter/src/widgets/navigator.dart:2554:9)
#1 Navigator.of (package:flutter/src/widgets/navigator.dart:2561:6)
#2 Navigator.push (package:flutter/src/widgets/navigator.dart:2019:22)
#3 MyAppState.build.<anonymous closure> (package:liveasy_task_flutter/main.dart:52:33)
#4 _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1072:21)
#5 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:253:24)
#6 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:627:11)
#7 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:306:5)
#8 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:239:7)
#9 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:615:9)
#10 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)
#11 PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
#12 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13)
#13 PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
#14 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)
#15 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:460:19)
#16 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:440:22)
#17 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:337:11)
#18 GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:395:7)
#19 GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:357:5)
#20 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:314:7)
#21 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:295:7)
#22 _invoke1 (dart:ui/hooks.dart:167:13)
#23 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:341:7)
#24 _dispatchPointerDataPacket (dart:ui/hooks.dart:94:31)
Handler: "onTap"
Recognizer: TapGestureRecognizer#1dfff
debugOwner: GestureDetector
state: possible
won arena
finalPosition: Offset(183.0, 459.8)
finalLocalPosition: Offset(32.0, 18.0)
button: 1
sent tap down
2
Answers
In your code the
MaterialApp
uses aNavigator
widget internally, so that’s good. But the thing is that thecontext
that you use is defined above it. Meaning that that context doesn’t have aNavigator
. An easy solution that might be unintuitive to beginners is to move theMaterialApp
to outside the widget, like this:This way, the
context
in thebuild
method ofMyAppState
does have an ancestor that is aNavigator
widget.look at the widgets in Flutter as a tree, with the context pointing to whichever node is being built with the build function. In your case, you have,
So when you are using the context to find the Navigator, you’re using a context for the main screen which isn’t under the navigator.
You can make a new Stateless or Stateful Widget to contain your Center and ElevatedButton, as the build function within those will point at that level instead, or you can use a Builder and define the builder callback (which has a context pointing at the Builder) to return the Center + ElevatedButton.