如何为Stateful Widget创建Flutter路由?
如何为Stateful Widget创建Flutter路由?
我在我的Flutter应用程序中收到了请求了一个不包含导航器的上下文的Navigator操作
的错误日志。所有我看到的例子都是针对“无状态”小部件的,所以我认为这可能是问题所在,或者是我的代码有问题?我该如何导航到我的LoginPage
?以下是没有任何导航器或路由的代码...
void main() {
runApp(new MyApp());
}
final googleSignIn = new GoogleSignIn();
final fb = FirebaseDatabase.instance.reference();
final auth = FirebaseAuth.instance;
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State
String _platformVersion = 'Unknown';
@override
initState() {
super.initState();
initPlatformState();
}
initPlatformState() async {
String platformVersion;
try {
platformVersion = await Myfavkpopflutter.platformVersion;
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
void MyFavAction() {
setState(() {
print("MYFAV");
});
}
void SearchAction() {
setState(() {
print("Search");
});
}
@override
Widget build(BuildContext context) {
if (auth.currentUser == null) {
return new MaterialApp(
routes:
'/settings': (BuildContext context) => new LoginPage(),
},
home: new Scaffold(
backgroundColor: Colors.white70,
appBar: new AppBar(
title: new Text(
"MyFavKPop",
style: new TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25.00,
),
),
backgroundColor: Colors.amber,
),
body: new Container(
child: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children:
new RaisedButton(
onPressed: MyFavAction,
color: Colors.lightBlue,
elevation: 20.00,
splashColor: Colors.amber,
child: new Text(
"MyFav KPOP",
style: new TextStyle(
color: Colors.black,
fontSize: 20.00,
),
),
),
new Padding(padding: new EdgeInsets.all(30.00)),
new RaisedButton(
onPressed: SearchAction,
color: Colors.lightBlue,
elevation: 20.00,
splashColor: Colors.amber,
child: new Text(
"MyFav SEARCH",
style: new TextStyle(
color: Colors.black,
fontSize: 20.00,
),
),
),
new Padding(
padding: new EdgeInsets.all(30.00),
),
new RaisedButton(
onPressed: SearchAction,
elevation: 20.00,
splashColor: Colors.amber,
color: Colors.lightBlue,
child: new Text(
"MyFav FRIENDS",
style: new TextStyle(
color: Colors.black,
fontSize: 20.00,
),
),
),
new Padding(
padding: new EdgeInsets.all(30.00),
),
new RaisedButton(
onPressed: SearchAction,
elevation: 20.00,
splashColor: Colors.amber,
color: Colors.lightBlue,
child: new Text(
"MyFav CHAT",
style: new TextStyle(
color: Colors.black,
fontSize: 20.00,
),
),
),
new Padding(
padding: new EdgeInsets.all(30.00),
),
new RaisedButton(
onPressed: SearchAction,
elevation: 20.00,
splashColor: Colors.amber,
color: Colors.lightBlue,
child: new Text(
"MyFav #1'S",
style: new TextStyle(
color: Colors.black,
fontSize: 20.00,
),
),
)
],
),
),
),
floatingActionButton: new FloatingActionButton(
child: new Text(
"Log Out",
style: new TextStyle(
fontWeight: FontWeight.bold,
fontSize: 12.00,
),
),
onPressed: () => Navigator.of(context).pushNamed('/settings'),
),
),
);
}
}
}
class LoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Login / Signup"),
),
body: new Container(
child: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children:
new TextField(
decoration: new InputDecoration(
hintText: "E M A I L A D D R E S S",
),
),
new Padding(padding: new EdgeInsets.all(15.00)),
new TextField(
obscureText: true,
decoration: new InputDecoration(hintText: "P A S S W O R D"),
),
new Padding(padding: new EdgeInsets.all(15.00)),
new TextField(
decoration: new InputDecoration(hintText: "U S E R N A M E"),
),
new RaisedButton(
onPressed: null,
child: new Text("SIGNUP"),
),
new Padding(padding: new EdgeInsets.all(15.00)),
new RaisedButton(
onPressed: null,
child: new Text("LOGIN"),
),
new Padding(padding: new EdgeInsets.all(15.00)),
new RaisedButton(
onPressed: null,
child: new Text("Facebook"),
),
new Padding(padding: new EdgeInsets.all(5.00)),
new RaisedButton(
onPressed: null,
child: new Text("Google"),
),
],
),
),
margin: new EdgeInsets.all(15.00),
),
);
}
}
**** 编辑这是我得到的错误日志...
══╡ 在处理手势时捕获的异常 ╞════════════════════════════════════════════════════════════════════════════════════════════════════
在不包含导航器的上下文中请求的导航器操作。
用于推送或弹出路由的上下文必须是导航器小部件的后代的上下文。
════════════════════════════════════════════════════════════════════════════════════════════════════
问题出现的原因是标题中提到的问题是导航到一个有状态的小部件(StatefulWidget),但是正文中询问的是如何导航到一个无状态的小部件(StatelessWidget)LoginPage。
解决方法如下:
1. 在你的主函数中,使用runApp()
来启动你的应用程序,并设置MaterialApp
作为根小部件。
2. 在MaterialApp
的home
参数中设置你的登录页为初始页面,可以是一个有状态的小部件。
3. 在MaterialApp
的routes
参数中设置路由表,其中键是路由名称,值是对应页面的构建器函数。
4. 在你的登录页中,使用Navigator.of(context).pushNamed()
来导航到其他页面。
以下是一个示例代码:
// 导入本地文件
import 'MyTabs.dart' as first;
.....
// 主函数
void main() {
runApp( new MaterialApp(
home: new SignIn(),
routes: <String, WidgetBuilder>{
"/mytabs" : (BuildContext context)=> new first.MyTabs(),
// 可以在这里添加更多的路由
},
));
}
我的应用程序从一个登录页面开始,这里展示了一个简化版。
class SignIn extends StatelessWidget {
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Sign In"),
),
body: new IconButton(icon: new Icon(Icons.arrow_forward), onPressed: (){Navigator.of(context).pushNamed("/mytabs");}),
)
希望这能帮到你,尝试按照这个流程来编写你的代码,并告诉我它的运行情况。
明白了。当我将路由放在void main()
中而不是初始页面类中时,它运行成功了。
这个问题的出现原因是用户在创建Flutter路由时遇到了错误,并且他们的代码中缺少了对Navigator的调用。此外,用户还犯了一个常见的错误,即在应用程序中有多个MaterialApp,而实际上只能有一个MaterialApp。以下是解决该问题的方法:
1. 确保你的代码中有对Navigator的调用,以便正确导航到所需的路由。
2. 确保你的应用程序中只有一个MaterialApp。你可以在MaterialApp中提供不同的路由。
下面是一个示例代码,展示了如何创建一个带有stateful widget的Flutter路由:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => HomePage(),
'/second': (context) => SecondPage(),
},
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Page'),
),
body: Center(
child: RaisedButton(
child: Text('Go to Second Page'),
onPressed: () {
Navigator.pushNamed(context, '/second');
},
),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Page'),
),
body: Center(
child: RaisedButton(
child: Text('Go Back'),
onPressed: () {
Navigator.pop(context);
},
),
),
);
}
}
通过阅读该代码,并将其与你自己的代码进行比较,你应该能够找到问题所在并解决它。希望这可以帮助到你!