管理多个页面时有两个核心概念和类:Route和 Navigator。 一个Route是一个屏幕或页面的抽象,Navigator是管理Route的Widget。Navigator可以通过route入栈和出栈来实现页面之间的跳转。
1、Route
Route 一个页面要想被路由统一管理,必须包装为一个Route。
Route是一个抽象类,进入Route类,点击cmd+opt+B查看其实现类。
imag01.png
/**
* 使用 MaterialPageRoute
* Android: 从屏幕底部滑动到顶部
* iOS: 从屏幕右侧滑动到左侧
*/
Navigator.of(context).push(MaterialPageRoute(builder: (ctx) {
return FirstPage("a home message---first");
}));
/**
* 使用PageRouteBuilder渐变效果
*/
Navigator.of(context).push(PageRouteBuilder(pageBuilder: (ctx, anim1, anim2) {
return FadeTransition(
opacity: anim1, child: FirstPage("a home message----first"));
}));
2、Navigator
Navigator:管理所有的Route的Widget,通过一个Stack来进行管理的。
// 路由跳转:传入一个路由对象
Future<T> push<T extendsObject>(Route<T> route)
// 路由跳转:传入一个名称(命名路由)
Future<T> pushNamed<T extendsObject>(
String routeName, {
Object arguments,
})
// 路由返回:可以传入一个参数
bool pop<T extendsObject>([ T result ])
- 实现从一个页面跳转到FirstPage页面并实现相互传值。
Future result=Navigator.of(context).push(MaterialPageRoute(builder: (ctx) {
return FirstPage("first params");
}));
result.then((value){
print("pop 返回---$value");
});
import 'package:flutter/material.dart';
class FirstPage extends StatelessWidget {
static const routeName="/firstPage";
final String _message;
FirstPage(this._message);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("first page"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(_message, style: TextStyle(fontSize: 20),),
RaisedButton(
child: Text("first pop"),
onPressed: () {
Navigator.of(context).pop("first pop");
},
),
],
),
),
);
}
}
- 通过命名路由实现跳转到SecondPage,先要在入口配置路由。
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter widget',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routes: {
//命名路由
SecondPage.routeName:(context)=>SecondPage(),
ThirdPage.routeName: (context) => ThirdPage(),
},
//由于FirstPage已经创建了构造器
onGenerateRoute: (settings){
if (settings.name == FirstPage.routeName) {
return MaterialPageRoute(
builder: (context) {
return FirstPage(settings.arguments);
}
);
}
return null;
},
//未知路由
onUnknownRoute: (settings){
return MaterialPageRoute(
builder: (context){
return UnKnownPage();
}
);
},
home: MyHomePage(),
);
}
}
Navigator.of(context).pushNamed(SecondPage.routeName, arguments: "a home message-03");
SecondPage代码,里面获取参数
import 'package:flutter/material.dart';
class SecondPage extends StatelessWidget {
static const routeName="/secondPage";
@override
Widget build(BuildContext context) {
final _message = ModalRoute.of(context).settings.arguments as String;
return Scaffold(
appBar: AppBar(
title: Text("second page"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(_message, style: TextStyle(fontSize: 20),),
RaisedButton(
child: Text("second pop"),
onPressed: () {
Navigator.of(context).pop("second pop");
},
),
],
),
),
);
}
}
- 监听页面的返回按钮的两种方式
appBar: AppBar(
title: Text("third page"),
leading: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.of(context).pop("third page back");
},
),
),
import 'package:flutter/material.dart';
class ThirdPage extends StatelessWidget {
static const routeName = "/thirdPage";
@override
Widget build(BuildContext context) {
final _message = ModalRoute.of(context).settings.arguments as String;
return WillPopScope(
onWillPop: () {
// 当返回为true时,flutter自动帮助我们执行返回操作
// 当返回为false时, 自行写返回代码
Navigator.of(context).pop("third page back");
return Future.value(false);
},
child: Scaffold(
appBar: AppBar(
title: Text("third page"),
// leading: IconButton(
// icon: Icon(Icons.arrow_back_ios),
// onPressed: () {
// Navigator.of(context).pop("third pop");
// },
// ),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
_message,
style: TextStyle(fontSize: 20),
),
RaisedButton(
child: Text("third pop"),
onPressed: () {
Navigator.of(context).pop("third page back");
},
),
],
),
),
),
);
}
}
网友评论