skip to Main Content

I’m developing a Flutter application and I’m trying to navigate to a LoginPage or RegisterPage using Navigator.push when an item from the PopupMenuButton in the app bar’s menu is selected. However, the navigation doesn’t always work as expected, and I’m not sure what’s going wrong.

When I select either ‘Login’ or ‘Register’ from the menu bar’s PopupMenuButton, the navigation sometimes doesn’t work, and nothing happens. I’ve checked the code but can’t seem to identify the issue.

**Here is the relevant part of my code:
**

import 'package:flutter/material.dart';

void main() {
  runApp(const PosApp());
}

class PosApp extends StatefulWidget {
  const PosApp({super.key});

  @override
  _PosAppState createState() => _PosAppState();
}

class _PosAppState extends State<PosApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text("NEOPOS"),
          backgroundColor: Colors.blue,
          actions: <Widget>[
            PopupMenuButton<String>(
              icon: const Icon(Icons.menu),
              onSelected: (value) => _handleClick(value),
              itemBuilder: (BuildContext context) {
                return {'Login', 'Register'}.map((String choice) {
                  return PopupMenuItem<String>(
                    value: choice,
                    child: Text(choice),
                  );
                }).toList();
              },
            ),
          ],
        ),
        body: Center(
          child: RichText(
            textAlign: TextAlign.center,
            text: const TextSpan(
              children: [
                TextSpan(
                  text: "NEOPOSn",
                  style: TextStyle(
                    fontSize: 30.0,
                    fontWeight: FontWeight.bold,
                    color: Colors.black,
                  ),
                ),
                TextSpan(
                  text: "NEOWEP SOFTWARE",
                  style: TextStyle(
                    fontSize: 18.0,
                    color: Colors.black,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  void _handleClick(String value) {
    switch (value) {
      case 'Login':
        Navigator.push(
          context,
          MaterialPageRoute(builder: (context) => const LoginPage()),
        );
        break;
      case 'Register':
        Navigator.push(
          context,
          MaterialPageRoute(builder: (context) => const RegisterPage()),
        );
        break;
    }
  }
}

class LoginPage extends StatelessWidget {
  const LoginPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Login'),
      ),
      body: const Center(
        child: Text('Login Page'),
      ),
    );
  }
}

class RegisterPage extends StatelessWidget {
  const RegisterPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Register'),
      ),
      body: const Center(
        child: Text('Register Page'),
      ),
    );
  }
}

Is there a known issue with using Navigator.push in conjunction with a PopupMenuButton in the menu bar, or am I missing something in my setup? Any guidance would be greatly appreciated.

Thank you in advance for your help!

I expected that when selecting either "Login" or "Register" from the menu bar’s PopupMenuButton, the app would navigate to the corresponding page without any issues. However, in some cases, the navigation does not happen, and the current screen remains unchanged. I want to understand why this inconsistency occurs and how to fix it.

4

Answers


  1. please try with the context pass in the parameters it’s may be error of context

     import 'package:flutter/material.dart';
    
    void main() {
      runApp(const PosApp());
    }
    
    class PosApp extends StatefulWidget {
      const PosApp({super.key});
    
      @override
      _PosAppState createState() => _PosAppState();
    }
    
    class _PosAppState extends State<PosApp> {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            appBar: AppBar(
              title: const Text("NEOPOS"),
              backgroundColor: Colors.blue,
              actions: <Widget>[
                PopupMenuButton<String>(
                  icon: const Icon(Icons.menu),
                  onSelected: (value) => _handleClick(context, value),
                  itemBuilder: (BuildContext context) {
                    return {'Login', 'Register'}.map((String choice) {
                      return PopupMenuItem<String>(
                        value: choice,
                        child: Text(choice),
                      );
                    }).toList();
                  },
                ),
              ],
            ),
            body: Center(
              child: RichText(
                textAlign: TextAlign.center,
                text: const TextSpan(
                  children: [
                    TextSpan(
                      text: "NEOPOSn",
                      style: TextStyle(
                        fontSize: 30.0,
                        fontWeight: FontWeight.bold,
                        color: Colors.black,
                      ),
                    ),
                    TextSpan(
                      text: "NEOWEP SOFTWARE",
                      style: TextStyle(
                        fontSize: 18.0,
                        color: Colors.black,
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      }
    
      void _handleClick(BuildContext context, String value) {
        switch (value) {
          case 'Login':
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => const LoginPage()),
            );
            break;
          case 'Register':
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => const RegisterPage()),
            );
            break;
        }
      }
    }
    
    class LoginPage extends StatelessWidget {
      const LoginPage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Login'),
          ),
          body: const Center(
            child: Text('Login Page'),
          ),
        );
      }
    }
    
    class RegisterPage extends StatelessWidget {
      const RegisterPage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Register'),
          ),
          body: const Center(
            child: Text('Register Page'),
          ),
        );
      }
    }
    
    Login or Signup to reply.
  2. I suggest to create a home page and create the MaterialApp above this home widget, try this code:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MaterialApp(
        debugShowCheckedModeBanner: false,
        home: HomePage(),
      ));
    }
    
    class HomePage extends StatefulWidget {
      const HomePage({super.key});
    
      @override
      _HomePageState createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text("NEOPOS"),
            backgroundColor: Colors.blue,
            actions: <Widget>[
              PopupMenuButton<String>(
                icon: const Icon(Icons.menu),
                onSelected: _handleClick,
                itemBuilder: (BuildContext context) {
                  return {'Login', 'Register'}.map((String choice) {
                    return PopupMenuItem<String>(
                      value: choice,
                      child: Text(choice),
                    );
                  }).toList();
                },
              ),
            ],
          ),
          body: Center(
            child: RichText(
              textAlign: TextAlign.center,
              text: const TextSpan(
                children: [
                  TextSpan(
                    text: "NEOPOSn",
                    style: TextStyle(
                      fontSize: 30.0,
                      fontWeight: FontWeight.bold,
                      color: Colors.black,
                    ),
                  ),
                  TextSpan(
                    text: "NEOWEP SOFTWARE",
                    style: TextStyle(
                      fontSize: 18.0,
                      color: Colors.black,
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    
      void _handleClick(String value) {
        switch (value) {
          case 'Login':
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => const LoginPage()),
            );
            break;
          case 'Register':
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => const RegisterPage()),
            );
            break;
        }
      }
    }
    
    class LoginPage extends StatelessWidget {
      const LoginPage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Login'),
          ),
          body: const Center(
            child: Text('Login Page'),
          ),
        );
      }
    }
    
    class RegisterPage extends StatelessWidget {
      const RegisterPage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Register'),
          ),
          body: const Center(
            child: Text('Register Page'),
          ),
        );
      }
    }
    
    Login or Signup to reply.
  3. In your code sample, you’re using outer context which doesn’t have a navigator attached to it, so it requires context which has navigator which will be solved by wrapping it into another widget that provides context with a navigator class attached by the Material widget.

    Try the below solution:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const PosApp());
    }
    
    class PosApp extends StatefulWidget {
      const PosApp({super.key});
    
      @override
      _PosAppState createState() => _PosAppState();
    }
    
    class _PosAppState extends State<PosApp> {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: HomePage(),
        );
      }
    }
    
    class HomePage extends StatelessWidget {
      const HomePage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text("NEOPOS"),
            backgroundColor: Colors.blue,
            actions: <Widget>[
              PopupMenuButton<String>(
                icon: const Icon(Icons.menu),
                onSelected: (value) => _handleClick(context, value),
                itemBuilder: (BuildContext context) {
                  return {'Login', 'Register'}.map((String choice) {
                    return PopupMenuItem<String>(
                      value: choice,
                      child: Text(choice),
                    );
                  }).toList();
                },
              ),
            ],
          ),
          body: Center(
            child: RichText(
              textAlign: TextAlign.center,
              text: const TextSpan(
                children: [
                  TextSpan(
                    text: "NEOPOSn",
                    style: TextStyle(
                      fontSize: 30.0,
                      fontWeight: FontWeight.bold,
                      color: Colors.black,
                    ),
                  ),
                  TextSpan(
                    text: "NEOWEP SOFTWARE",
                    style: TextStyle(
                      fontSize: 18.0,
                      color: Colors.black,
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    
      void _handleClick(BuildContext context, String value) {
        print(value);
        switch (value) {
          case 'Login':
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => const LoginPage()),
            );
            break;
          case 'Register':
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => const RegisterPage()),
            );
            break;
        }
      }
    }
    
    class LoginPage extends StatelessWidget {
      const LoginPage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Login'),
          ),
          body: const Center(
            child: Text('Login Page'),
          ),
        );
      }
    }
    
    class RegisterPage extends StatelessWidget {
      const RegisterPage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Register'),
          ),
          body: const Center(
            child: Text('Register Page'),
          ),
        );
      }
    }
    
    
    Login or Signup to reply.
  4. I checked your code in my IDE and after some logs, I found this error after

    Navigator.push(context, MaterialPageRoute(builder: (context) => const LoginPage()));

    is executed :

    Navigator operation requested with a context that does not include a Navigator

    I found some helpful hints about the error on this link, which I suggest to read.

    Now the solution for you:

    1. First of of all, as in some codes I have seen, returning MaterialApp in widget build is not usual, instead you should directly return scaffold and change main method as follows:
    void main() {
      runApp(const MaterialApp(home: PosApp()));
    }
    

    This will work, but if you get another error with red screen, try the second step too.

    1. In the class PosApp extends StatefulWidget replace _PosAppState with State<PosApp.>. So your code will be like this:
    void main() {
      runApp(const MaterialApp(home: PosApp()));
    }
    
    
    class PosApp extends StatefulWidget {
      const PosApp({super.key});
    
      @override
      State<PosApp> createState() => _PosAppState();
    }
    
    class _PosAppState extends State<PosApp> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            //code
        );
      }
    

    I wish these work for you.

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