简体   繁体   中英

Calling Navigator outside Widget build() gives context error

So I'm basically trying to check if users have seen an Intro page in my flutter app. If they already have seen it, I want them to be directed to the Login() page. Else, I want them to be directed to the IntroScreen() page.

However, I am getting the following error: Unhandled Exception: Navigator operation requested with a context that does not include a Navigator. E/flutter (13982): 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. Unhandled Exception: Navigator operation requested with a context that does not include a Navigator. E/flutter (13982): 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.

This is my code:

void main() => runApp(CheckSplash());

//check if the intro screen has already been seen
class CheckSplash extends StatefulWidget {
  @override
  _CheckSplashState createState() => _CheckSplashState();
}

class _CheckSplashState extends State<CheckSplash> {

  bool _introseen=true;
  Future checkIntroSeen() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    bool _introseen = (prefs.getBool('seen') ?? false);

    if (_introseen) {
      Navigator.of(context).pushReplacement(
          new MaterialPageRoute(builder: (BuildContext context) => Login()));
    } else {
      //await prefs.setBool('seen', true);
      Navigator.of(context).pushReplacement(
          new MaterialPageRoute(builder: (BuildContext context) => new IntroScreen()));
    }
  }

  @override
  void initState() {
    super.initState();
    new Timer(new Duration(milliseconds: 200), () {
      checkIntroSeen();
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        theme: appTheme,
        debugShowCheckedModeBanner: false,
        home: Builder(
            builder: (context) => Scaffold(
                resizeToAvoidBottomPadding: false,
                body: Center(child: CircularProgressIndicator(valueColor: new AlwaysStoppedAnimation<Color>(Colors.red[300])))
            )
        )
    );
  }
}

So I solved the problem by using the flutter GET library. Link: flutter get library

Using this library, one doesn't need the context to navigate between pages and thus it is a full proof method to navigate from anywhere in flutter.

I Have tried the easiest way. Create a function for your code after your contextBuilder. Then, Just put the context as a function argument:

 Widget build(BuildContext context) { return ....(your code) } yourFunction(context) { Navigator.pop(context); Navigator.push(context, MaterialPageRoute(builder: (context) => LoginScreen())); }

It is worked as expected for me. Thanks!

context inside initState is available inside SchedulerBinding.instance.addPostFrameCallback . This function fired after widget is built.

@override
void initState() {
  super.initState();

  SchedulerBinding.instance.addPostFrameCallback((_) {
    new Timer(new Duration(milliseconds: 200), () {
      checkIntroSeen();
    });
  });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM