1登渣、Flutter Router路由封裝
路由插件: fluro
1.1 在 pubspec.yaml
中加入下面代碼送矩,并獲取該依賴包
fluro: "^1.6.3"
1.2 在 lib
文件夾下新建一個(gè) router
文件夾,并新建 router.dart
和 router_handler.dart
兩個(gè)文件
1.2.1 router_handler.dart
文件
import 'package:fluro/fluro.dart'; // 引入路由包依賴文件
import 'package:flutter/cupertino.dart';
import 'package:new_flutter/pages/page_one.dart'; // page_one為第一個(gè)頁面
import 'package:new_flutter/pages/page_two.dart'; // page_two為第一個(gè)頁面
// 創(chuàng)建每個(gè)路由的 Handler函數(shù)
var pageOne = new Handler(
handlerFunc: (BuildContext context, Map<String,List<String>>params ){
return PageOne(); // PageOne 為 page_one 頁面的 StatelessWidget
}
);
var pageTwo = new Handler(
handlerFunc: (BuildContext context, Map<String,List<String>>params ){
return PageTwo(); // PageTwo 為 page_two 頁面的 StatelessWidget
}
);
1.2.2 router.dart
文件
import 'package:flutter/cupertino.dart';
import 'package:fluro/fluro.dart'; // 引入路由包依賴文件
import 'package:new_flutter/router/router_handler.dart'; // 每個(gè)頁面路由對(duì)應(yīng)的 Handler 函數(shù)文件
// 定義路由配置類
class Routers {
static String root = '/';
//路由配置
static void configRouters(Router router){
//找不到路由
router.notFoundHandler = new Handler(
handlerFunc: (BuildContext context,Map<String,List<String>> params){
print('ERROR====>ROUTE WAS NOT FONUND!!!');
return;
}
);
//整體配置
router.define('/pageOne', handler: pageOne); // page_one 頁面路由
router.define('/pageTwo', handler: pageTwo); // page_two 頁面路由
}
}
1.3 在 main.dart
中引入路由信息护赊,并初始化
import 'package:fluro/fluro.dart'; // 引入路由包依賴文件
import 'package:flutter/material.dart';
import 'package:new_flutter/pages/page_one.dart'; // 這里 page_one 作為應(yīng)用打開頁面
import 'package:new_flutter/router/router.dart'; // 路由信息文件
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
final GlobalKey<NavigatorState> navigatorKey = GlobalKey();
@override
Widget build(BuildContext context) {
//路由初始化
final router = Router();
Routers.configRouters(router);
return new MaterialApp(
title: 'Flutter App', // 設(shè)備用于為用戶識(shí)別應(yīng)用程序的單行描述
theme: ThemeData( // 應(yīng)用程序小部件使用的顏色。
primaryColor: Color.fromRGBO(222, 225, 231, 1)
),
color: Colors.red, // 在操作系統(tǒng)界面中應(yīng)用程序使用的主色瑰钮。
home: PageOne(), // 應(yīng)用程序默認(rèn)路由的小部件,用來定義當(dāng)前應(yīng)用打開的時(shí)候殖蚕,所顯示的界面
navigatorKey: navigatorKey, // 在構(gòu)建導(dǎo)航器時(shí)使用的鍵
onGenerateRoute: router.generator, // 應(yīng)用程序?qū)Ш降街付酚蓵r(shí)使用的路由生成器回調(diào)
);
}
}
1.4 創(chuàng)建頁面 page_one 和 page_two
1.4.1 page_one.dart (這里我做了一個(gè)按鈕轿衔,點(diǎn)擊跳轉(zhuǎn)至 page_two 頁面)
import 'package:flutter/material.dart';
class PageOne extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: new Scaffold(
appBar: new AppBar( // 頭部導(dǎo)航欄
title: new Text('我的 Flutter'),
),
body: new Center(
child: Column(
children:[
OutlineButton(
child: Text("normal"),
onPressed: () {
// pageOne 跳轉(zhuǎn)到 pageTwo頁面 ,
Navigator.of(context).pushNamed(
'/pageTwo', // router.dart 中定義的路由訪問鏈接
arguments: { 'id': 1} // arguments 傳遞的參數(shù)
);
},
)
]
),
),
),
);
}
}
1.4.2 page_two.dart (這里我接收從 page_one 頁面?zhèn)鬟f過來的參數(shù))
import 'package:flutter/material.dart';
class PageTwo extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 獲取路由傳參
print( ModalRoute.of(context).settings.arguments );
return MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text('page Two'),
),
body: new Center(
child: Text('page Two'),
),
),
);
}
}
注意:
MaterialApp({
Key key,
this.title = '', // 設(shè)備用于為用戶識(shí)別應(yīng)用程序的單行描述
this.home, // 應(yīng)用程序默認(rèn)路由的小部件,用來定義當(dāng)前應(yīng)用打開的時(shí)候,所顯示的界面
this.color, // 在操作系統(tǒng)界面中應(yīng)用程序使用的主色睦疫。
this.theme, // 應(yīng)用程序小部件使用的顏色害驹。
this.routes = const <String, WidgetBuilder>{}, // 應(yīng)用程序的頂級(jí)路由表
this.navigatorKey, // 在構(gòu)建導(dǎo)航器時(shí)使用的鍵。
this.initialRoute, // 如果構(gòu)建了導(dǎo)航器蛤育,則顯示的第一個(gè)路由的名稱
this.onGenerateRoute, // 應(yīng)用程序?qū)Ш降街付酚蓵r(shí)使用的路由生成器回調(diào)
this.onUnknownRoute, // 當(dāng) onGenerateRoute 無法生成路由(initialRoute除外)時(shí)調(diào)用
this.navigatorObservers = const <NavigatorObserver>[], // 為該應(yīng)用程序創(chuàng)建的導(dǎo)航器的觀察者列表
this.builder, // 用于在導(dǎo)航器上面插入小部件宛官,但在由WidgetsApp小部件創(chuàng)建的其他小部件下面插入小部件,或用于完全替換導(dǎo)航器
this.onGenerateTitle, // 如果非空瓦糕,則調(diào)用此回調(diào)函數(shù)來生成應(yīng)用程序的標(biāo)題字符串底洗,否則使用標(biāo)題。
this.locale, // 此應(yīng)用程序本地化小部件的初始區(qū)域設(shè)置基于此值咕娄。
this.localizationsDelegates, // 這個(gè)應(yīng)用程序本地化小部件的委托亥揖。
this.localeListResolutionCallback, // 這個(gè)回調(diào)負(fù)責(zé)在應(yīng)用程序啟動(dòng)時(shí)以及用戶更改設(shè)備的區(qū)域設(shè)置時(shí)選擇應(yīng)用程序的區(qū)域設(shè)置。
this.localeResolutionCallback,
this.supportedLocales = const <Locale>[Locale('en', 'US')], // 此應(yīng)用程序已本地化的地區(qū)列表
this.debugShowMaterialGrid = false, // 打開繪制基線網(wǎng)格材質(zhì)應(yīng)用程序的網(wǎng)格紙覆蓋
this.showPerformanceOverlay = false, // 打開性能疊加
this.checkerboardRasterCacheImages = false, // 打開柵格緩存圖像的棋盤格
this.checkerboardOffscreenLayers = false, // 打開渲染到屏幕外位圖的圖層的棋盤格
this.showSemanticsDebugger = false, // 打開顯示框架報(bào)告的可訪問性信息的覆蓋
this.debugShowCheckedModeBanner = true, // 在選中模式下打開一個(gè)小的“DEBUG”橫幅圣勒,表示應(yīng)用程序處于選中模式
})
1.5 自定義動(dòng)畫路由
很多時(shí)候费变,我們的項(xiàng)目中會(huì)有一些特殊的頁面切換動(dòng)效,此時(shí)我們就需要自定義路由動(dòng)畫圣贸,flutter
中 PageRouteBuilder
提供了一個(gè) Animation
對(duì)象挚歧,Animation
能夠通過結(jié)合 Tween
以及 Curve
對(duì)象來自定義路由轉(zhuǎn)換動(dòng)畫
PageRouteBuilder
屬性
PageRouteBuilder({
RouteSettings settings, // 路由基本信息
@required this.pageBuilder, // 創(chuàng)建跳轉(zhuǎn)的路由頁面
this.transitionsBuilder = _defaultTransitionsBuilder, // 自定義的轉(zhuǎn)場(chǎng)效果
this.transitionDuration = const Duration(milliseconds: 300), // 轉(zhuǎn)場(chǎng)動(dòng)畫的持續(xù)時(shí)間
this.opaque = true, // 是否遮擋整個(gè)屏幕
this.barrierDismissible = false,
this.barrierColor, // 路由回退時(shí)頁面動(dòng)畫陰影顏色
this.barrierLabel,
this.maintainState = true, // 默認(rèn)情況下,當(dāng)入棧一個(gè)新路由時(shí)吁峻,原來的路由仍然會(huì)被保存在內(nèi)存中滑负,如果想在路由沒用的時(shí)候釋放其所占用的所有資源,可以設(shè)maintainState為false
bool fullscreenDialog = false, // 表示新的路由頁面是否是一個(gè)全屏的模態(tài)對(duì)話框锡搜,在iOS中橙困,如果fullscreenDialog為true,新頁面將會(huì)從屏幕底部滑入(而不是水平方向)耕餐。
})
1.5.1 搭建一個(gè) PageRouteBuilder
/*
* Widget nextPage 下一個(gè)路由組件
* Tween tween 定義的頁面動(dòng)畫過程
*/
PageRouteBuilder(
// 設(shè)置路由基本信息Settings凡傅,可通過它獲取當(dāng)前路由、上個(gè)頁面路由
settings: new RouteSettings(
name: '$nextPage'
),
// 用來生成要顯示的Widget
pageBuilder: (context,animation,secondaryAnimation) => nextPage,
// 設(shè)置轉(zhuǎn)場(chǎng)動(dòng)畫的效果
transitionsBuilder: (context, animation, secondaryAnimation, child){
return SlideTransition(
position: animation.drive(
tween.chain(CurveTween( curve: Curves.ease))
),
child: child
);
},
// 設(shè)置了動(dòng)畫時(shí)長(zhǎng)
transitionDuration:const Duration(milliseconds: 600)
);
1.5.2 創(chuàng)建 Tween
為了使新頁面從底部動(dòng)畫出來肠缔,它應(yīng)該從 Offset(0,1) 到 Offset(0, 0) 進(jìn)行動(dòng)畫 Offset( dx, dy )夏跷。(通常我們會(huì)使用 Offset.zero 構(gòu)造器。)在這個(gè)情況下明未,對(duì)于 ‘FractionalTranslation’ widget 來說偏移量是一個(gè) 2D 矢量值槽华。將 dy 參數(shù)設(shè)為 1,這代表在豎直方向上切換整個(gè)頁面的高度趟妥。
// 動(dòng)畫Map表
Map tweenObj = {
'rightIn' : Tween( begin: Offset(1,0), end: Offset.zero ),
'leftIn' : Tween( begin: Offset(-1,0), end: Offset.zero ),
'topIn' : Tween( begin: Offset(0,-1), end: Offset.zero ),
'bottomIn' : Tween( begin: Offset(0,1), end: Offset.zero ),
};
1.5.3 使用 AnimatedWidget
Flutter 有一堆繼承自 AnimatedWidget
的 widget猫态,它們能夠在動(dòng)畫的值發(fā)生改變時(shí)自動(dòng)重建自己。舉個(gè)例子,SlideTransition
拿到一個(gè) Animation<Offset>
并在動(dòng)畫改變時(shí)使用 FractionalTranslation widget
轉(zhuǎn)換其子級(jí)亲雪。
AnimatedWidget
返回了一個(gè)帶有 Animation<Offset>
的 SlideTransition
勇凭,以及 child widget:
// 生成一個(gè)從右邊進(jìn)入的動(dòng)畫
var offsetAnimation = animation.drive(tweenObj['rightIn']);
1.5.4 使用 CurveTween
Curves 類提供了一個(gè)提前定義的用法相似的 curves
。例如义辕,Curves.easeOut
將會(huì)讓動(dòng)畫開始很快結(jié)束很慢虾标。
var curve = Curves.ease;
var curveTween = CurveTween(curve: curve);
1.5.5 結(jié)合兩個(gè) Tween
連接兩個(gè) Tween
需要用 chain()
:
var curve = Curves.ease;
var tween = tweenObj['rightIn'].chain(CurveTween(curve: curve));
1.5.6 完整的項(xiàng)目代碼實(shí)例 -- 封裝自定義路由跳轉(zhuǎn)函數(shù)
// 引入項(xiàng)目包
import 'package:flutter/material.dart';
import 'package:fluro/fluro.dart';
// 路由跳轉(zhuǎn)公共函數(shù)
// ignore: missing_return
Future<Null> jumpPage(BuildContext context, String method, Widget nextPage, String animate){
// 動(dòng)畫Map表
Map tweenObj = {
'rightIn' : Tween( begin: Offset(1,0), end: Offset.zero ),
'leftIn' : Tween( begin: Offset(-1,0), end: Offset.zero ),
'topIn' : Tween( begin: Offset(0,-1), end: Offset.zero ),
'bottomIn' : Tween( begin: Offset(0,1), end: Offset.zero ),
};
// 定義 PageRouteBuilder 函數(shù)
Route _createRoutee(Tween tween){
// 利用 PageRouteBuilder 來創(chuàng)建 Route
return PageRouteBuilder(
// 設(shè)置路由基本信息Settings,可通過它獲取當(dāng)前路由灌砖、上個(gè)頁面路由
settings: new RouteSettings(
name: '$nextPage'
),
// 用來生成要顯示的Widget
pageBuilder: (context,animation,secondaryAnimation) => nextPage,
// 設(shè)置轉(zhuǎn)場(chǎng)動(dòng)畫的效果
transitionsBuilder: (context, animation, secondaryAnimation, child){
return SlideTransition(
position: animation.drive(
tween.chain(CurveTween( curve: Curves.ease))
),
child: child
);
},
// 設(shè)置了動(dòng)畫時(shí)長(zhǎng)
transitionDuration:const Duration(milliseconds: 600)
);
}
switch(method){
// 將設(shè)置的router信息推送到Navigator上璧函,實(shí)現(xiàn)頁面跳轉(zhuǎn)。
case 'push':
Navigator.push(context, _createRoutee(tweenObj[animate]));
break;
// 路由替換基显。
case 'pushReplacement':
Navigator.pushReplacement(context, _createRoutee(tweenObj[animate]));
break;
// 從Navigator中刪除路由蘸吓,同時(shí)執(zhí)行Route.dispose操作。
case 'removeRoute':
Navigator.removeRoute(context, _createRoutee(tweenObj[animate]));
break;
// 將給定路由推送到Navigator撩幽,刪除先前的路由美澳,直到該函數(shù)的參數(shù)predicate返回true為止。
case 'pushAndRemoveUntil':
Navigator.pushAndRemoveUntil(context, _createRoutee(tweenObj[animate]), (route) => false);
break;
// 從Navigator中刪除路由摸航,同時(shí)執(zhí)行Route.dispose操作。
case 'removeRoute':
Navigator.removeRoute(context, _createRoutee(tweenObj[animate]));
break;
// 導(dǎo)航到新頁面舅桩,或者返回到上個(gè)頁面酱虎。
case 'pop':
Navigator.pop(context,_createRoutee(tweenObj[animate]));
break;
}
}
1.5.7 項(xiàng)目中使用封裝的路由跳轉(zhuǎn)函數(shù)做跳轉(zhuǎn)
在需要用到跳轉(zhuǎn)的組件中引入封裝的文件,并使用跳轉(zhuǎn)函數(shù) jumpPage
// 引入依賴包
import 'package:new_flutter/utils/util.dart'; // 封裝的路由跳轉(zhuǎn)函數(shù)的文件
import 'package:new_flutter/pages/next_page.dart'; // 需要跳轉(zhuǎn)到的組件
onPressed: () async{
/*
* push 路由跳轉(zhuǎn)的方法名
* NextPage 需要跳轉(zhuǎn)的下一個(gè)路由組件
* topIn 需要用到的路由動(dòng)畫名
*/
jumpPage(context, 'push', NextPage(), 'topIn');
},
1.6 路由監(jiān)聽 RouteObserver
當(dāng)頁面路由進(jìn)行路由跳轉(zhuǎn)時(shí)擂涛,RouteObserver
就會(huì)通知訂閱者读串。例如,每當(dāng)用戶從當(dāng)前頁面路線導(dǎo)航到另一個(gè)頁面路線時(shí)撒妈,RouteObserver<PageRoute>
都會(huì)通知訂閱的 RouteAware
對(duì)其 Route
狀態(tài)的更改恢暖。
在項(xiàng)目中添加全局路由監(jiān)聽
在 main.dart
文件中添加全局路由監(jiān)聽邏輯:
1、將 RouteObserver 注冊(cè)為全局導(dǎo)航觀察器
// 全局的路由監(jiān)聽者狰右,可在需要的widget中添加杰捂,應(yīng)該放到一個(gè)全局定義的文件中
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
2、定義路由監(jiān)聽類
class MyRouterLister extends NavigatorObserver{
@override
// push 路由監(jiān)聽
void didPush(Route route, Route previousRoute) {
super.didPush(route, previousRoute);
var previousName = '';
if (previousRoute == null) {
previousName = 'null';
}else {
previousName = previousRoute.settings.name;
}
print('添加路由:' + route.settings.name + ' Previous:' + previousName);
}
@override
// pop 路由監(jiān)聽
void didPop(Route route, Route previousRoute) {
super.didPop(route, previousRoute);
var previousName = '';
if (previousRoute == null) {
previousName = 'null';
}else {
previousName = previousRoute.settings.name;
}
print('pop路由:' + route.settings.name + ' Previous:' + previousName);
}
@override
// remove 路由監(jiān)聽
void didRemove(Route route, Route previousRoute) {
super.didRemove(route, previousRoute);
var previousName = '';
if (previousRoute == null) {
previousName = 'null';
}else {
previousName = previousRoute.settings.name;
}
print('remove路由:' + route.settings.name + ' Previous:' + previousName);
}
@override
// replace 路由監(jiān)聽
void didReplace({Route newRoute,Route oldRoute}) {
super.didReplace();
var oldName = '';
if (oldRoute == null) {
oldName = 'null';
}else {
oldName = oldRoute.settings.name;
}
print('replace路由:' + newRoute.settings.name + ' old:' + oldName);
}
}
3棋蚌、把 routeObserver 這個(gè)東西傳遞給 MaterialApp 的 navigatorObservers ( 其實(shí)最終給到了 Navigator 嫁佳, MaterialApp widget 只是包裹了 Navigator )
final GlobalKey<NavigatorState> navigatorKey = GlobalKey();
final router = Router();
MaterialApp(
title: 'Flutter App', // 設(shè)備用于為用戶識(shí)別應(yīng)用程序的單行描述
theme: ThemeData( // 應(yīng)用程序小部件使用的顏色。
primaryColor: Color.fromRGBO(222, 225, 231, 1)
),
home: PageOne(), // 首頁
navigatorKey: navigatorKey, // 在構(gòu)建導(dǎo)航器時(shí)使用的鍵
onGenerateRoute: router.generator, // 應(yīng)用程序?qū)Ш降街付酚蓵r(shí)使用的路由生成器回調(diào)
navigatorObservers: [MyRouterLister(),routeObserver]
);
路由監(jiān)聽完整 main.dart
文件代碼
import 'package:fluro/fluro.dart';
import 'package:flutter/material.dart';
import 'package:new_flutter/router/router.dart'; // 路由配置文件
import 'package:new_flutter/pages/page_one.dart'; // PageOne 組件文件
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
final GlobalKey<NavigatorState> navigatorKey = GlobalKey();
@override
Widget build(BuildContext context) {
//路由初始化
final router = Router();
// 全局的路由監(jiān)聽者谷暮,可在需要的widget中添加蒿往,應(yīng)該放到一個(gè)全局定義的文件中
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
// Routers 為路由配置文件中的類
Routers.configRouters(router);
Application.router = router;
return new MaterialApp(
title: 'Flutter App', // 設(shè)備用于為用戶識(shí)別應(yīng)用程序的單行描述
theme: ThemeData( // 應(yīng)用程序小部件使用的顏色。
primaryColor: Color.fromRGBO(222, 225, 231, 1)
),
color: Colors.red, // 在操作系統(tǒng)界面中應(yīng)用程序使用的主色湿弦。
home: PageOne(), // 應(yīng)用程序默認(rèn)路由的小部件,用來定義當(dāng)前應(yīng)用打開的時(shí)候瓤漏,所顯示的界面
navigatorKey: navigatorKey, // 在構(gòu)建導(dǎo)航器時(shí)使用的鍵
onGenerateRoute: Application.router.generator, // 應(yīng)用程序?qū)Ш降街付酚蓵r(shí)使用的路由生成器回調(diào)
navigatorObservers: [MyRouterLister(),routeObserver],
);
}
}
class MyRouterLister extends NavigatorObserver{
@override
// push 路由監(jiān)聽
void didPush(Route route, Route previousRoute) {
super.didPush(route, previousRoute);
var previousName = '';
if (previousRoute == null) {
previousName = 'null';
}else {
previousName = previousRoute.settings.name;
}
print('添加路由:' + route.settings.name + ' Previous:' + previousName);
}
@override
// pop 路由監(jiān)聽
void didPop(Route route, Route previousRoute) {
super.didPop(route, previousRoute);
var previousName = '';
if (previousRoute == null) {
previousName = 'null';
}else {
previousName = previousRoute.settings.name;
}
print('pop路由:' + route.settings.name + ' Previous:' + previousName);
}
@override
// remove 路由監(jiān)聽
void didRemove(Route route, Route previousRoute) {
super.didRemove(route, previousRoute);
var previousName = '';
if (previousRoute == null) {
previousName = 'null';
}else {
previousName = previousRoute.settings.name;
}
print('remove路由:' + route.settings.name + ' Previous:' + previousName);
}
@override
// replace 路由監(jiān)聽
void didReplace({Route newRoute,Route oldRoute}) {
super.didReplace();
var oldName = '';
if (oldRoute == null) {
oldName = 'null';
}else {
oldName = oldRoute.settings.name;
}
print('replace路由:' + newRoute.settings.name + ' old:' + oldName);
}
}
// 路由靜態(tài)化
class Application {
static Router router;
}
注意: 當(dāng)我們使用自定義路由( PageRouteBuilder
)的時(shí)候,若有拿取路由棧中路由信息時(shí)蔬充,必須要設(shè)置 Settings
蝶俱,否則會(huì)出現(xiàn)路由丟失,路由信息都為 Null
1.7 Navigator
路由方法總結(jié)
Navigator
是一個(gè)路由管理的組件娃惯,它提供了打開和退出路由頁方法跷乐。Navigator
通過一個(gè)棧來管理活動(dòng)路由集合
push 將設(shè)置的router信息推送到Navigator上,實(shí)現(xiàn)頁面跳轉(zhuǎn)趾浅。
of 主要是獲取Navigator最近的Widget愕提。
pop 導(dǎo)航到新頁面,或者返回到上個(gè)頁面皿哨。
canPop 判斷是否可以導(dǎo)航到新頁面
maybePop 可能會(huì)導(dǎo)航到新頁面
popAndPushNamed 指定一個(gè)路由路徑浅侨,并導(dǎo)航到新頁面。
popUntil 反復(fù)執(zhí)行pop 直到該函數(shù)的參數(shù)predicate返回true為止证膨。
pushAndRemoveUntil 將給定路由推送到Navigator如输,刪除先前的路由,直到該函數(shù)的參數(shù)predicate返回true為止央勒。
pushNamedAndRemoveUntil 將命名路由推送到Navigator不见,刪除先前的路由,直到該函數(shù)的參數(shù)predicate返回true為止崔步。
pushNamed 將命名路由推送到Navigator稳吮。
pushReplacement 路由替換。
pushReplacementNamed 替換路由操作井濒。推送一個(gè)命名路由到Navigator灶似,新路由完成動(dòng)畫之后處理上一個(gè)路由。
removeRoute 從Navigator中刪除路由瑞你,同時(shí)執(zhí)行Route.dispose操作酪惭。
removeRouteBelow 從Navigator中刪除路由,同時(shí)執(zhí)行Route.dispose操作者甲,要替換的路由是傳入?yún)?shù)anchorRouter里面的路由春感。
replace 將Navigator中的路由替換成一個(gè)新路由。
replaceRouteBelow 將Navigator中的路由替換成一個(gè)新路由过牙,要替換的路由是是傳入?yún)?shù)anchorRouter里面的路由甥厦。