1 基礎(chǔ)知識
在了解Flutter的路由管理功能前胜茧,首先需要幾個(gè)基礎(chǔ)類有一定熟悉,以下簡單介紹路由相關(guān)幾個(gè)類的功能摇展。
類 | 功能 |
---|---|
Navigator | 導(dǎo)航器洋闽,管理路由的Widget |
Route及子類 | 用于Navigator管理的頁面 |
RouteSettings及子類 | 保存頁面配置信息,如name休涤,arguments等 |
2 路由管理Navigator.push
管理Flutter路由分為兩種方式:
- 直接路由
- 命名路由
路由方式 | 實(shí)現(xiàn)方式 |
---|---|
直接路由 | Navigator.push調(diào)用咱圆,使用Route進(jìn)行路由 |
命名路由 | Navigator.pushNamed調(diào)用,使用routeName進(jìn)行路由 |
2.1 直接路由
2.1.1 源碼
@optionalTypeArgs
static Future<T?> push<T extends Object?>(BuildContext context, Route<T> route) {
return Navigator.of(context).push(route);
}
2.1.2 使用演示
從TestHomePage頁面路由到TestRouterPage功氨。
class TestHomePage extends StatelessWidget {
const TestHomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
ScreenUtil.init(context, designSize: const Size(375, 667));
return Scaffold(
body: GestureDetector(
child: Center(
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(border: Border.all(width: 1, color: Colors.red)),
child: const Text("This is a home page. This is a home page. This is a home page.",
textAlign: TextAlign.center, style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Colors.red)),
),
),
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return const TestRouterPage();
}));
// Navigator.pushNamed(context, TestRouterPage.routeName);
},
),
);
}
}
class TestRouterPage extends StatelessWidget {
const TestRouterPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(border: Border.all(width: 1, color: Colors.blue)),
child: const Text("This is a router page. ",
textAlign: TextAlign.center, style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Colors.blue)),
),
),
);
}
}
2.2 命名路由
2.2.1 源碼
@optionalTypeArgs
static Future<T?> pushNamed<T extends Object?>(
BuildContext context,
String routeName, {
Object? arguments,
}) {
return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
}
2.2.2 配置使用
s1.通用路由配置類
class TestRouter {
// 此處用于后續(xù)通用路由配置
static Map<String, Function> routes = {
TestRouterPage.routeName: (context) => const TestRouterPage(),
};
// 配置到MaterialApp的onGenerateRoute中
var onGenerateRoute = (RouteSettings settings) {
final String? name = settings.name;
final Function? pageBuilder = routes[name];
if (pageBuilder != null) {
if (settings.arguments != null) {
// 帶參數(shù)路由
final Route route = MaterialPageRoute(builder: (context) => pageBuilder(context), settings: settings);
return route;
} else {
// 無參數(shù)路由
final Route route = MaterialPageRoute(builder: (context) => pageBuilder(context));
return route;
}
}
return MaterialPageRoute(builder: (context) => WebPage(const Page404()));
};
}
s2.路由配置類加到APP啟動的MaterialApp的onGenerateRoute中
class TestApp extends StatelessWidget {
const TestApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(primaryColor: Colors.blue, primaryTextTheme: TextTheme()),
onGenerateRoute: TestRouter().onGenerateRoute,
home: const TestHomePage(),
);
}
}
2.2.3 使用演示
Navigator.pushNamed(context, TestRouterPage.routeName);
3 路由管理Navigator.pop
3.1 源碼
@optionalTypeArgs
static void pop<T extends Object?>(BuildContext context, [ T? result ]) {
Navigator.of(context).pop<T>(result);
}
3.2 使用演示
從TestRouterConstructPage頁面后退到TestHomePage序苏。
class TestRouterConstructPage extends StatelessWidget {
late Map _argu;
TestRouterConstructPage(this._argu, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
child: Center(
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(border: Border.all(width: 1, color: Colors.blue)),
child: Text(
"This is a router construct page. argMap = $_argu",
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Colors.blue),
),
)),
onTap: () {
Navigator.pop(context);
},
),
);
}
}
4 Navigator.popUntil
4.1 源碼
static void popUntil(BuildContext context, RoutePredicate predicate) {
Navigator.of(context).popUntil(predicate);
}
4.2 使用演示
從TestRouterConstructPage頁面后退到首頁【TestHomePage】。
class TestRouterConstructPage extends StatelessWidget {
late Map _argu;
TestRouterConstructPage(this._argu, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
child: Center(
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(border: Border.all(width: 1, color: Colors.blue)),
child: Text(
"This is a router construct page. argMap = $_argu",
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Colors.blue),
),
)),
onTap: () {
Navigator.popUntil(context, (route) => route.isFirst);
},
),
);
}
}
跳轉(zhuǎn)指定頁
// 頁面push跳轉(zhuǎn)
Navigator.push(context, MaterialPageRoute(settings: const RouteSettings(name: "/TestHomePage"), builder: (context) => TestHomePage()));
// 頁面pop跳轉(zhuǎn)
Navigator.popUntil(context, ModalRoute.withName("/TestHomePage")),
關(guān)于路由及Navigator.push和Navigator.pop的參數(shù)處理部分在下一節(jié)中繼續(xù)詳細(xì)說明捷凄。