在 Widget build() 外部调用 Navigator 会产生上下文错误

Calling Navigator outside Widget build() gives context error

所以我基本上是在尝试检查用户是否在我的 flutter 应用程序中看到了介绍页面。如果他们已经看到它,我希望他们被定向到 Login() 页面。否则,我希望他们被定向到 IntroScreen() 页面。

但是,我收到以下错误: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.

这是我的代码:

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])))
            )
        )
    );
  }
}

contextinitState 内可用在 SchedulerBinding.instance.addPostFrameCallback 内。此函数在构建小部件后触发。

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

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

所以我使用flutterGET库解决了这个问题。 Link: flutter get library

使用这个库,不需要上下文在页面之间导航,因此它是一种在 flutter 中从任何地方导航的完整证明方法。

我试过最简单的方法。在 contextBuilder 之后为您的代码创建一个函数。然后,只需将 context 作为函数参数:

Widget build(BuildContext context) {
  return ....(your code)
}

yourFunction(context) {
  Navigator.pop(context);
  Navigator.push(context, MaterialPageRoute(builder: (context) => LoginScreen()));
}

它对我来说是按预期工作的。谢谢!