管理多個頁面時有兩個核心概念和類:Route 和 Navigator。 一個Route是一個螢幕或頁面的抽象,Navigator是管理Route的Widget。Navigator可以通過route入棧和出棧來實現頁面之間的跳轉。
1、Route
Route 一個頁面要想被路由統一管理,必須包裝為一個Route。 Route是一個抽象類,進入Route類,點選cmd+opt+B檢視其實現類。
/**
* 使用 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");
},
),
],
),
),
),
);
}
}
複製程式碼