Flutter 之路由
2023-10-15 本文已影响0人
Abner_XuanYuan
1、路由介绍
Flutter 中的路由通俗的讲就是页面跳转。在 Flutter 中通过 Navigator 组件管理路由导航。并提供了管理堆栈的方法。如:Navigator.push 和 Navigator.pop。
Flutter 中给我们提供了两种配置路由跳转的方式:1、基本路由 2、命名路由。
2、普通路由
例:从 HomePage 组件跳转到 SearchPage 组件。
1、需要在 HomPage 中引入 SearchPage.dart
import './testLib/SearchPage.dart';
2、在 HomePage 中跳转
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("页面跳转"),
),
backgroundColor: Colors.grey,
body: Center(
child: ElevatedButton(
onPressed: () {
//通过以下方法实现跳转
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return const SearchPage();
}));
},
child: const Text("页面跳转按钮")),
),
);
}
}
传值
1、SearchPage 页面
import 'package:flutter/material.dart';
class SearchPage extends StatelessWidget {
final String title;
const SearchPage({super.key, this.title = "Search"});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.orange,
appBar: AppBar(
title: Text(title),
centerTitle: true,
),
body: Center(
child: Container(
color: Colors.green,
child: const Text("搜索页面视图"),
),
),
);
}
}
2、HomePage 页面
// 以下为传值时的代码
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("页面跳转"),
),
backgroundColor: Colors.grey,
body: Center(
child: ElevatedButton(
onPressed: () {
//通过以下方法实现跳转
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
// return const SearchPage();
return const SearchPage(title: "搜索vvvvv",); //传值
}));
},
child: const Text("页面跳转按钮")),
),
);
}
}
3、命名路由
1、无参跳转
配置 routes
import 'package:flutter/material.dart';
import './pages/tabs.dart';
import './pages/search.dart';
import './pages/form.dart';
void main(List<String> args) {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
// home: HomePage(),
initialRoute: '/', //初始化路由
routes: { //跳转路由(更改建议:调整为路由表)
'/':(contxt)=>const Tabs(),
'/search':(contxt) => const SearchPage(),
'/form': (context) => const FormPage(), },
);
}
}
跳转
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/form');
},
child: const Text("跳转到form页面")),
2、有参跳转
配置 onGenerateRoute
import 'package:flutter/material.dart';
import './pages/tabs.dart';
import './pages/search.dart';
import './pages/form.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
//1、定义Map类型的routes
Map routes = {
'/': (contxt) => const Tabs(),
'/search': (contxt) => const SearchPage(), //注意:命名路由无需传值方式
'/form': (context, {arguments}) => FormPage(arguments: arguments), //注意:命名路由需要传值方式
};
MyApp({Key? key}) : super(key: key);
@override Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/', //初始化路由
//2、配置 onGenerateRoute
onGenerateRoute: (RouteSettings settings) {
// 统一处理
final String? name = settings.name; //路由名称,如:/form
final Function? pageContentBuilder = routes[name]; // Function,如:(contxt) => const SearchPage()
if (pageContentBuilder != null) {
if (settings.arguments != null) { //是否有传参
final Route route = MaterialPageRoute(
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments));
return route;
} else {
final Route route = MaterialPageRoute(
builder: (context) => pageContentBuilder(context));
return route;
}
}
return null;
},
);
}
}
定义页面接收 arguments 参数
import 'package:flutter/material.dart';
class FormPage extends StatefulWidget {
final Map arguments; //接收参数
const FormPage({super.key,required this.arguments});
@override
State<FormPage> createState() => _FormPageState();
}
class _FormPageState extends State<FormPage> {
@override
void initState() {
print(widget.arguments);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("我是一个Form表单演示页面"),
),
);
}
}
跳转
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/form',arguments: { //传参
"title": "搜索页面",
});
},
child: const Text("form")
)
3、命名路由方法封装
在路由文件中配置公共路由和 onGenerateRoute
//1、导入头文件
import 'package:flutter/material.dart';
import '../pages/tabs.dart';
import '../pages/search.dart';
import '../pages/news.dart';
import '../pages/form.dart';
import '../pages/shop.dart';
//2、配置路由(路由中字符串(key)可以进一步进行宏定义封装)
Map routes = {
"/": (contxt) => const Tabs(),
"/news": (contxt) => const NewsPage(),
"/search": (contxt) => const SearchPage(),
"/form": (contxt, {arguments}) => FormPage(arguments: arguments),
"/shop": (contxt, {arguments}) => ShopPage(arguments: arguments),
};
//3、配置 onGenerateRoute (固定写法,这个方法也相当于一个中间件,这里可以做权限判断)
var onGenerateRoute = (RouteSettings settings) {
final String? name = settings.name;
final Function? pageContentBuilder = routes[name];
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = MaterialPageRoute(
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments));
return route;
} else {
final Route route =
MaterialPageRoute(builder: (context) => pageContentBuilder(context));
return route;
}
}
return null;
};
路由跳转配置
import 'package:flutter/material.dart';
import './routers/routers.dart'; //导入路由文件
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
//路由跳转
initialRoute: "/", //初始化路由
onGenerateRoute: onGenerateRoute, //路由跳转
);
}
}
使用
//无参
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/news");
},
child: const Text("命名路由跳转news")),
//有参
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, "/shop",
arguments: {"title": "shop传值", "aid": 21});
},
child: const Text("命名路由传值Shop")),
4、路由相关方法
返回上一级路由
Navigator.of(context).pop();
路由替换:跳转到指定页面
Navigator.of(context).pushReplacementNamed('/registerSecond');
返回到根路由
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (BuildContext context) {
return const Tabs();
}), (route) => false);
路由跳转风格
Material 组件库中提供了一个 MaterialPageRoute 组件,它可以使用和平台风格一致的路由切换动画,如在 iOS 平台上会左右滑动切换,而在 Android 上会上下滑动切换 。CupertinoPageRoute 是 Cupertino 组件库提供的 iOS 风格的路由切换组件如果在 Android 上也想使用左右切换风格,可以使用 CupertinoPageRoute。
使用方法
1、引入 cupertino.dart
import 'package:flutter/cupertino.dart';
2、MaterialPageRoute 改为 CupertinoPageRoute
///测试示例
import 'package:flutter/cupertino.dart'; //注意:引入头文件
import '../pages/tabs.dart';
import '../pages/shop.dart';
import '../pages/user/login.dart';
import '../pages/user/registerFirst.dart';
import '../pages/user/registerSecond.dart';
import '../pages/user/registerThird.dart';
//1、配置路由
Map routes = {
"/": (contxt) => const Tabs(),
"/login": (contxt) => const LoginPage(),
"/registerFirst": (contxt) => const RegisterFirstPage(),
"/registerSecond": (contxt) => const RegisterSecondPage(),
"/registerThird": (contxt) => const RegisterThirdPage(),
"/shop": (contxt, {arguments}) => ShopPage(arguments: arguments),
};
//2、配置onGenerateRoute 固定写法 这个方法也相当于一个中间件,这里可以做权限判断
var onGenerateRoute = (RouteSettings settings) {
final String? name = settings.name; // /news 或者 /search
final Function? pageContentBuilder = routes[name];
Function = (contxt) { return const NewsPage()}
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = CupertinoPageRoute( //MaterialPageRoute 改为 CupertinoPageRoute
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments));
return route;
} else {
final Route route =
CupertinoPageRoute(builder: (context) => pageContentBuilder(context)); //MaterialPageRoute 改为 CupertinoPageRoute
return route;
}
}
return null;
};