Flutterapp页⾯路由以及路由拦截的实现
⽬录
为什么要使⽤路由
Flutter路由介绍
页⾯结构与逻辑
实现关键代码
页⾯路由跳转
为什么要使⽤路由
在之前我们的代码中,页⾯跳转使⽤的代码如下所⽰:
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => LoginPage()),
)
;
在开发过程中,随着页⾯的增加,如果继续使⽤这种⽅式会有如下缺陷:
代码耦合严重:涉及到页⾯跳转的地⽅就需要插⼊页⾯的构造函数,意味着需要知道其他页⾯的构建⽅式。
不易维护:⼀旦某个页⾯发⽣了变化,需要将涉及到该页⾯的跳转全部改变。
权限控制不⽅便:假设某些页⾯需要授权后才可以访问,需要在各个地⽅插⼊权限判断。
Flutter路由介绍
⾸先说⼀下,本篇的路由介绍是 Flutter 1.0的实现⽅式,Flutter 2.0对路由做了很⼤的改动,使⽤了声明式⽅式重构了路由,使⽤起来会更为复杂。在 Flutter 的 MaterialApp提供了路由配置参数,当使⽤路由配置后,MaterialApp 的构造形式如下所⽰:
return MaterialApp(
//其他参数...
navigatorKey: //全局导航状态Key,
onGenerateRoute: //路由改变响应⽅法,
initialRoute: //初始化路由路径,
);
navigatorKey是⼀个GlobalKey<NavigatorState>对象,⽤于全局存储导航的状态。
onGenerateRoute为⼀个路由,当路由发⽣改变时,该⽅法会被调⽤,从⽽可以根据路由参数返回不同的页⾯,或者进⾏路由拦截。
initialRoute为初始化路由路径,⼀般为启动页或⾸页的路径。
页⾯结构与逻辑
为了演⽰路由的使⽤,我们使⽤了四个页⾯:
AppHomePage :⾸页,与之前的章节的页⾯框架⼀样,路由路径为“/”;
Splash:启动页,只有⼀个图⽚,实际使⽤过程可以⽤于加载引导页,⼴告或其他⽤途。页⾯停留2秒后切换到⾸页。
LoginPage:登录页,⽤于演⽰点击登录按钮通过路由切换到登录页。
NotFound:即404页⾯,当路由表中没有匹配的路径时,跳转到404页⾯。
这⾥的路由跳转分为了两种,⼀是从启动页跳转到⾸页,这种跳转不可返回的;⼆是正常的调整,可以点击返回按钮返回到上⼀级。在 Flutter 中提供不同的⽅法应对这两种情况。
实现关键代码
⾸先是路由表和路由拦截响应的实现,在 routers⽂件夹新建 router_table.dart ⽂件,代码如下:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../app.dart';
import '../login.dart';
import '../not_found.dart';
import '../splash.dart';
class RouterTable {
static String splashPath = 'splash';
static String loginPath = 'login';
flutter开发appstatic String homePath = '/';
static String notFoundPath = '404';
static Map<String, WidgetBuilder> routeTables = {
//404页⾯
notFoundPath: (context) => NotFound(),
//启动页
splashPath: (context) => Splash(),
//登录
loginPath: (context) => LoginPage(),
//⾸页
homePath: (context) => AppHomePage(),
};
///路由拦截
static Route onGenerateRoute<T extends Object>(RouteSettings settings) {
return CupertinoPageRoute<T>(
settings: settings,
builder: (context) {
String name = settings.name;
if (routeTables[name] == null) {
name = notFoundPath;
}
Widget widget = routeTables[name](context);
return widget;
},
);
}
}
这⾥全部使⽤了静态属性和静态⽅法,是为了可以直接从过类名访问属性和⽅法,⽽⽆需反复构建对象。
这样,路由访问的时候也可以通过类名的静态属性直接访问,可以避免拼写错误。有了这个类了后,App 的所有页⾯都可以通过这个类集中管理,从⽽避免多处维护了。
这⾥关键的是onGenerateRoute⽅法,该⽅法接收了⼀个 RouteSettings 对象,该对象会有个 name 属性包含路由路径名称,同时还有个 arguments ⽤于携带路由参数。可以通过这个属性来与路由表的页⾯进⾏匹配。若匹配到则返回相应的页⾯;若没有匹配到,则路由到404页⾯。同时,若需要做权限控制,也可以在这⾥拦截,⽐如定位到403页⾯或直接提醒⽆访问权限。
接下来就是改造 main.dart ⽂件,在构建 MaterialApp 时使⽤对应的理由配置:
import 'package:flutter/material.dart';
import 'routers/router_table.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final GlobalKey navigationKey = GlobalKey<NavigatorState>();
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: navigationKey,
onGenerateRoute: GenerateRoute,
initialRoute: RouterTable.splashPath,
);
}
}
这⾥会发现在 main.dart中我们⽆需再通过 import引⼊相关的页⾯了,⽽是直接配置路由的配置属性即可。
页⾯路由跳转
页⾯路由跳转更为简便,在 Flutter 中的 NavigatorState 中分别提供了 pushNamed ⽅法和pushReplacementNamed ⽅法,前者会在导航栏有返回按钮,后者是使⽤路由后的页⾯直接替换当前页⾯,适⽤于启动页的调整。在启动页中未来停留⼏秒,
使⽤了⼀个定时器,在2秒后再进⾏跳转,实际可以⽤于做⼀些预加载资源的提⽰或者⼴告展⽰。
@override
void didChangeDependencies() {
super.didChangeDependencies();
if (!_initialized) {
_initialized = true;
Timer(const Duration(milliseconds: 2000), () {
Navigator.of(context).pushReplacementNamed(RouterTable.homePath);
});
}
}
普通页⾯的跳转直接使⽤ pushNamed 即可,若要返回上⼀级,则使⽤ pop ⽅法。push 和 pop⽅法均可以携带参数,下⼀篇我们再来介绍如何处理路由参数。这⾥我们特意加了⼀个错误的路由演⽰404跳转:
body: Center(
child: Column(
mainAxisAlignment: ,
children: [
ButtonUtil.primaryTextButton('登录', () {
Navigator.of(context).pushNamed(RouterTable.loginPath);
}, context),
SizedBox(
height: 10,
),
ButtonUtil.primaryTextButton('404', () {
Navigator.of(context).pushNamed('errorRoute');
}, context),
],
),
),
最终运⾏效果如下图所⽰。
以上就是Flutter app页⾯路由以及路由拦截的实现的详细内容,更多关于Flutter 路由的资料请关注其它相关⽂章!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论