Flutter路由——Navigator2.0

news/2024/11/29 11:35:48/

Navigator 2.0提供了一系列全新的接口,可以实现将路由状态成为应用状态的一部分,新增的API如下:

  • Page:用来表示Navigator路由栈中各个页面的不可变对象,Page是一个抽象类通常使用它的派生类:MaterialPage或CupertinoPage;
  • Router:用来配置要用Navigator展示的页面列表,通常该页面列表会根据系统或应用程序的状态改变而改变,除了直接使用Router本身外还可以使用MaterialApp.router()来创建Router;
  • RouterDelegate:定义应用程序中的路由行为,例如Router如何知道应用程序状态的变化以及如何响应,监听RouteInformationParser和应用状态,并使用当前列表来构建Pages;
  • RouteInformationParser:可缺省,主要应用于web,持有RouteInformationProvider提供的RouteInformation,可以将其解析为我们定义的数据类型;
  • BackButtonDispatcher:响应后退按钮,并通知Router;

上面的API中BackButtonDispatcher很少用到,对于移动端来说,只需要用到Page、Router和RouterDelegate这三个API即可。

RouterDelegate与Router、RouteInformationParser在一起的交互和应用程序的状态如下:
在这里插入图片描述

  • 1.当系统打开一个新页面时,RouteInformationParser会将其转换为应用中的具体数据类型T;
  • 2.该数据类型会被传递给RouterDelegate的setNewRoutePath方法,我们可以在这里更新路由状态;
  • 3.notifyListeners会通知Router重建RouterDelegate;
  • 4.RouterDelegate.build()返回一个新的Navigator实例,并最终展示出打开的页面;

代码实例:

/// @description hu
import 'package:flutter/material.dart';
import 'package:up_china/model/video_model.dart';
import 'package:up_china/page/home_page.dart';
import 'package:up_china/page/video_detail_page.dart';void main() {runApp(UPApp());
}class UPApp extends StatefulWidget {State<StatefulWidget> createState() => _UPAppState();
}class _UPAppState extends State<UPApp> {UPDelegate _routerDelegate = UPRouterDelegate();UPRouteInformationParser _routeInformationParser =UPRouteInformationParser();Widget build(BuildContext context) {print('_UPAppState:build');//定义routevar widget = Router(routeInformationParser: _routeInformationParser,routerDelegate: _routerDelegate,///routeInformationParser为null时可缺省,routeInformation提供者routeInformationProvider: PlatformRouteInformationProvider(initialRouteInformation: RouteInformation(location: '/')),);return MaterialApp(home: widget);}
}class UPRouterDelegate extends RouterDelegate<UPRoutePath>with ChangeNotifier, PopNavigatorRouterDelegateMixin<UPRoutePath> {final GlobalKey<NavigatorState> navigatorKey;UPRoutePath path;List<MaterialPage> pages = [];VideoModel videoModel;//为Navigator设置一个key,必要的时候可以通过navigatorKey.currentState来获取到NavigatorState对象UPRouterDelegate() : navigatorKey = GlobalKey<NavigatorState>();Widget build(BuildContext context) {//构建路由栈pages = [pageWrap(HomePage(onJumpToDetail: (mo) {this.videoModel = mo;notifyListeners();},)),if (videoModel != null)pageWrap(VideoDetailPage(videoModel),)];print('UPRouterDelegate:build');return Navigator(key: navigatorKey,pages: pages,onPopPage: (route, result) {print('Navigator:onPopPage');//在这里可以控制是否可以返回if (!route.didPop(result)) {return false;}return true;},);}//路由初始化时,Router 会调用setNewRoutePath 方法来更新应用程序的路由状态:Future<void> setNewRoutePath(UPRoutePath path) async {print('UPRouterDelegate:setNewRoutePath:$path');this.path = path;}
}///可缺省,主要应用与web,持有RouteInformationProvider 提供的 RouteInformation ,可以将其解析为我们定义的数据类型。
class UPRouteInformationParser extends RouteInformationParser<UPRoutePath> {Future<UPRoutePath> parseRouteInformation(RouteInformation routeInformation) async {final uri = Uri.parse(routeInformation.location);print('UPRouteInformationParser:parseRouteInformation:uri:$uri');if (uri.pathSegments.length == 0) {return UPRoutePath.home();}return UPRoutePath.detail();}
}///定义路由path
class UPRoutePath {final String location;UPRoutePath.home() : location = "/";UPRoutePath.detail() : location = "/detail";
}///创建Page
pageWrap(Widget child) {return MaterialPage(key: ValueKey(child.hashCode),child: child,);
}
  • APP启动:
    1.启动;
    2.RouteInformationParser:parseRouteInformation;
    3.RouterDelegate:build;
    4.RouterDelegate:setNewRoutePath;
    5.RouterDelegate:build;
  • 打开页面:RouterDelegate:build 返回一个新的Navigator实例,并展示新的页面;
  • 返回:Navigator:onPopPage;
    在这里插入图片描述

http://www.ppmy.cn/news/280913.html

相关文章

P1522 [USACO2.4]牛的旅行 Cow Tours(Floyd多源最短路)

洛谷&#xff1a;牛的旅行 Cow son Tours 毒瘤题意&#xff08;确信&#xff09; 此题数据很小&#xff0c;但题意不好分析 洛谷题解整理的概念就很好&#xff08;分析能力%%%&#xff09;&#xff1a; 牧区&#xff1a; 对应一个点。牧区之间的距离&#xff1a;实际上是两点…

1522 N 叉树的直径

题目描述&#xff1a; 给定一棵 N 叉树的根节点 root &#xff0c;计算这棵树的直径长度。 N 叉树的直径指的是树中任意两个节点间路径中 最长 路径的长度。这条路径可能经过根节点&#xff0c;也可能不经过根节点。 &#xff08;N 叉树的输入序列以层序遍历的形式给出&#xf…

Oracle12c创建1522端口实例 和删除实例

1.手动添加1522监听 选第一项 添加 输入新监听名称 任意即可 输入你的oracl密码 ,也就是下载时候的密码 ,一般都是orcl 点击下一步完成创建即可 手动添加完监听&#xff0c;开始创建实例 以管理员身份运行cmd&#xff0c;输入dbca 第一个 全局数据库名就是你的实例名&…

洛谷 P1522

题目 链接&#xff1a;https://www.luogu.com.cn/problem/P1522 思路 这个题有些坑 1 可能重连接后没有之前长 最长的还是以前的 2 一个点也可能是一个区域 代码 #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include…

10g RAC 修改监听端口

11gRAC修改端口&#xff1a; http://blog.csdn.net/bamuta/article/details/29863943 11gRAC增加监听1&#xff1a; http://blog.csdn.net/bamuta/article/details/29865023 11gRAC增加监听2&#xff1a; http://blog.csdn.net/bamuta/article/details/300294…

给Oracle数据库换一个1522端口的监听

可能是因为短了几天&#xff0c;2月过得比其他月份要快不少。这都最后一天了&#xff0c;博客还是没碰一下。 也因为这个月学习放缓了&#xff0c;就是偷懒了。。所以想了想&#xff0c;定不下要写些什么。 很久以前就想写写分析函数&#xff0c;Oracle的分析函数是个强大的东…

Pytest自动化测试框架生成allure的报告

一、前言 最近通过群友了解到了allure这个报告&#xff0c;开始还不以为然&#xff0c;但还是逃不过真香定律。 经过试用之后&#xff0c;发现这个报告真的很好&#xff0c;很适合自动化测试结果的展示。下面说说我的探索历程吧。 选用的项目为Selenium自动化测试Pytest框架实…

Docker安装达梦(DM)关系型数据库,DBeaver远程连接使用数据库

Docker安装达梦&#xff08;DM&#xff09;关系型数据库 首先你得去达梦数据库官网注册一个账号。 下载数据库部署包 官网&#xff1a;https://www.dameng.com/ 然后找到需要的数据库&#xff1a; 官网试用地址&#xff1a;https://eco.dameng.com/tour/?source_urlht…