skip to Main Content

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


  1. In your code the MaterialApp uses aNavigator widget internally, so that’s good. But the thing is that the context that you use is defined above it. Meaning that that context doesn’t have a Navigator. An easy solution that might be unintuitive to beginners is to move the MaterialApp to outside the widget, like this:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MaterialApp(home: MyApp()));
    }
    
    class MyApp extends StatefulWidget {
      @override
      MyAppState createState() => MyAppState();
    }
    
    class MyAppState extends State<MyApp>{
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return 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"),
                      )
                    ],
                  ),
                )
    
        );
      }
    }
    

    This way, the context in the build method of MyAppState does have an ancestor that is a Navigator widget.

    Login or Signup to reply.
  2. 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,

    MainScreen    <------ the context
      --> MaterialApp
       (--> Navigator built within MaterialApp)
          --> Scaffold
            --> body
              --> Center
                --> ElevatedButton
    

    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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search