目录
首先新建两个路由
路由跳转的两种方式
方式一:push跳转
Navigator.push(context, MaterialPageRoute(builder: (context) { return SecondApp();}));
或者
Navigator.push(context, MaterialPageRoute(builder: (context) => SecondApp();));
或者
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>SecondApp()));
void main() => runApp(MainApp());
class MainApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return First();
}
}
class First extends State<MainApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Builder(
builder: buildScaffold,
),
);
}
}
Widget buildScaffold(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title:
Text("第一个页面", style: TextStyle(fontSize: 18, color: Colors.white)),
),
body: RaisedButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return SecondApp();
}));
},
color: Colors.blue,
child: Text(
"跳转到下一个页面",
style: TextStyle(fontSize: 25, color: Colors.white),
)));
}
运行:
方式二:routes命名路由跳转
- 关于routes的声明,是要依附在MaterialApp中
routes: {
"/page_two": (context) => SecondApp(),
}
void main() => runApp(MainApp());
class MainApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return FirstApp();
}
}
class FirstApp extends State<MainApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {
"page_two":(context)=>SecondApp()
},
home: Builder(
builder: buildScaffold,
),
);
}
}
Widget buildScaffold(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title:
Text("第一个页面", style: TextStyle(fontSize: 18, color: Colors.white)),
),
body: RaisedButton(
onPressed: () {
Navigator.pushNamed(context, "page_two");
},
color: Colors.blue,
child: Text(
"跳转到下一个页面",
style: TextStyle(fontSize: 25, color: Colors.white),
)));
}
运行:
页面返回
Navigator.pop
直接在按钮监听处添加 Navigator.pop(context);
查看源码,会发现,这里有可选参数result,这里可以处理返回值,下面会讲到
传值
通过构造函数传值(不够灵活)
- 这里只是举了一个简单的例子,传递String类型,当然也可以定义传递对象,传递数组,道理是一样的
routes: { "page_two":(context)=>SecondApp(content:"你好") }
class SecondApp extends StatefulWidget {
String content;
SecondApp({this.content});
@override
State<StatefulWidget> createState() {
return Second();
}
}
class Second extends State<SecondApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("第二个页面",
style: TextStyle(fontSize: 18, color: Colors.white)),
),
body: RaisedButton(
onPressed: () {
Navigator.pop(context);
},
color: Colors.blue,
child: Text(
widget.content+" 点我返回",
style: TextStyle(fontSize: 25, color: Colors.white),
))),
);
}
}
运行:
通过Todos列表
首先先建一个Todos实体类
class Todo { String title; Todo(this.title); }
传值:
Navigator.pushNamed(context, "page_two",arguments: Todo("你好"));
或者:
Navigator.push(context, MaterialPageRoute(builder: (context)=>SecondApp(), settings: RouteSettings(arguments: Todo("你好"))));
接收:
void main() => runApp(MainApp());
class MainApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return First();
}
}
class First extends State<MainApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("第一个页面",
style: TextStyle(fontSize: 18, color: Colors.white)),
),
body: RaisedButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return SecondApp();
}));
},
color: Colors.blue,
child: Text(
"跳转到下一个页面",
style: TextStyle(fontSize: 25, color: Colors.white),
)
)
),
);
}
}
接收返回数据
async+await异步方式
接收返回的数据肯定是个耗时操作,所以必须要是异步的
void _reset(BuildContext context) async{
final result=await Navigator.pushNamed(context, "page_two", arguments: Todo("你好"));
setState(() {
str=result as String;
});
}
void main() => runApp(MainApp());
class MainApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return FirstApp();
}
}
class FirstApp extends State<MainApp> {
String str = "跳转到下一个页面";
void _reset(BuildContext context) async{
final result=await Navigator.pushNamed(context, "page_two", arguments: Todo("你好"));
setState(() {
str=result as String;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {"page_two": (context) => SecondApp()},
home: Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("第一个页面",
style: TextStyle(fontSize: 18, color: Colors.white)),
),
body: Builder(builder: (context) {
return RaisedButton(
onPressed: () {
_reset(context);
},
color: Colors.blue,
child: Text(
str,
style: TextStyle(fontSize: 25, color: Colors.white),
));
})),
);
}
}
Future方式
Future对象表示异步操作的结果,我们通常通过then()回调来处理返回的结果
Future future = Navigator.pushNamed(context, "page_two", arguments: Todo("你好"));
future.then((value) { _reset(value); });
class MainApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return FirstApp();
}
}
class FirstApp extends State<MainApp> {
String str = "跳转到下一个页面";
void _reset(String data) {
setState(() {
str = data;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {"page_two": (context) => SecondApp()},
home: Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("第一个页面",
style: TextStyle(fontSize: 18, color: Colors.white)),
),
body: Builder(builder: (context) {
return RaisedButton(
onPressed: () {
Future future = Navigator.pushNamed(context, "page_two",
arguments: Todo("你好"));
future.then((value) {
_reset(value);
});
},
color: Colors.blue,
child: Text(
str,
style: TextStyle(fontSize: 25, color: Colors.white),
));
})),
);
}
}
运行:
push路由跳转失效的原因?
Flutter在一些包的层级比较多子Widget里无法直接用过Navigator.of(context).push方法来进行跳转,主要是因为子Widget的Context无法执行跳转操作,只能使用页面的BuildContext来进行跳转
所以在上面的案例中,都会在最外层包裹一层Builder