4. 路由
4.1 靜態(tài)路由
靜態(tài)路由(即命名路由)
靜態(tài)路由在通過Navigator跳轉之前,需要在MaterialApp組件內顯式聲明路由的名稱,而一旦聲明,路由的跳轉方式就固定了。通過在MaterialApp內的routes屬性進行顯式聲明路由的定義。
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Flutter Demo",
theme: ThemeData(primarySwatch: Colors.blue),
// home: const Tabs(),
initialRoute: "/",
routes: {
"/": (context) => const Tabs(),
/*
也可以使用大括號的寫法
"/": (context) { reutnr const Tabs() },
*/
"/s": (context) => const Search(
title: '',
)
},
);
}
}
注:使用命名路由時,home 要注釋掉,使用 initialRoute
class _MessageState extends State<Message> {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
// 命名路由跳轉頁面方式
Navigator.pushNamed(context, "/s",
arguments: {"title": "我是標題", "content": "我是內容"});
},
child: const Text("跳轉搜索頁面"))
],
),
);
}
}
4.2 動態(tài)路由
動態(tài)路由無需在MaterialApp內的routes中注冊即可直接使用:RootPage —> Apage
Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {
return const Search();
}
)
);
動態(tài)路由中,需要傳入一個Route,這里使用的是MaterialPageRoute,它可以使用和平臺風格一致的路由切換動畫,在iOS上左右滑動切換,Android上會上下滑動切換。也可以使用CupertinoPageRoute實現(xiàn)全平臺的左右滑動切換。
當然也可以自定義路由切換動畫,使用PageRouteBuilder:使用FadeTransition
做一個漸入過渡動畫。
使用 CupertinoPageRoute 時,需要引入 import 'package:flutter/cupertino.dart';
Navigator.of(context).push(
PageRouteBuilder(
transitionDuration: Duration(milliseconds: 250), // //動畫時間為0.25秒
pageBuilder: (BuildContext context,Animation animation,
Animation secondaryAnimation){
return FadeTransition( //漸隱漸入過渡動畫
opacity: animation,
child: Search()
);
}
)
);
在這之前有必要說明:
Navigator.of(context).push和Navigator.push兩著并沒有特別的區(qū)別,看源碼也得知,后者其實就是調用了前者。
of:獲取Navigator當前已經實例的狀態(tài)。
4.3 跳轉傳值
接收值
import 'package:flutter/material.dart';
class Search extends StatefulWidget {
final String title;
final String content;
const Search({super.key, required this.title, this.content = "默認內容"});
@override
State<Search> createState() => _SearchState();
}
class _SearchState extends State<Search> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// 通過 widget 進行取值的操作
title: Text(widget.title),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(widget.content),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text("返回上一頁"))
],
),
);
}
}
傳值
import 'package:flutter/material.dart';
import '../search.dart';
class Message extends StatefulWidget {
const Message({super.key});
@override
State<Message> createState() => _MessageState();
}
class _MessageState extends State<Message> {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (BuildContext context) {
return const Search(
title: '搜索Title',
content: "我是傳過去的值",
);
}));
},
child: const Text("跳轉搜索頁面"))
],
),
);
}
}
4.4 pop
返回當前路由棧的上一個界面。
Navigator.pop(context);
4.5 替換路由
第一頁面 -> 第二頁面 -> 第三頁面。
在第二個界面中,使用 pushReplacementNamed,跳轉到第三個頁面,在第三個頁面點返回時,就回到了第一個頁面。而不是第二個。
Navigator.of(context).pushReplacementNamed("/C");
4.6 返回跟路由
參考:http://www.itdecent.cn/p/beda41170b60
// 移除全部
Navigator.pushAndRemoveUntil(context, MaterialPageRoute(
builder: (context) {
return const Tabs();
},
), (route) => false);
// 或者
// 移除全部
Navigator.of(context).pushNamedAndRemoveUntil("/", (route) => false);