在 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])))
)
)
);
}
}
context
在 initState
内可用在 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()));
}
它对我来说是按预期工作的。谢谢!
所以我基本上是在尝试检查用户是否在我的 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])))
)
)
);
}
}
context
在 initState
内可用在 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()));
}
它对我来说是按预期工作的。谢谢!