关于Flutter Widget 生命周期之前写过一篇文章:Flutter关于StatefulWidget生命周期的理解。今天说说页面变化的另一个知识点RouteObserver
监听,算是对StatefulWidget
生命周期的补充。
RouteObserver
是一个专门用来观察导航栈中路由变化的对象。通过 RouteObserver
可以监听页面(或更确切地说,路由)的生命周期变化。具体来说,RouteObserver
可以监听页面的推入、弹出、替换等导航行为,并触发相应的回调函数,开发者可以利用它来做一些页面切换时的处理工作,比如统计页面访问时长、暂停和恢复动画、管理资源等。
使用场景
页面状态监控:监控页面切换、显示与隐藏,执行对应的逻辑操作。
导航栈管理:监控当前路由堆栈的状态变化,比如页面的入栈、出栈等操作。
统计和分析:在应用中记录用户页面停留时长,监控页面流转顺序。
动画暂停与恢复:当页面离开时暂停动画,返回时恢复动画。
基本结构
RouteObserver
是 NavigatorObserver
的子类,Flutter 中的 NavigatorObserver
用于监听 Navigator
的路由事件。通过 RouteObserver
,你可以监控路由(页面)进栈、出栈等变化事件。
RouteObserver 的主要方法
didPush
:当新的路由被推入到导航堆栈时触发,类似于页面的“打开”事件。didPop
:当路由从导航堆栈中弹出时触发,类似于页面的“关闭”事件。didRemove
:当某个路由被从导航堆栈中移除时触发。didReplace
:当某个路由被替换时触发。
RouteAware 接口
RouteAware
是一个接口,页面的 State
类可以实现这个接口,以便与 RouteObserver
进行交互。具体实现时,你可以在页面的 State
类中实现 didPush
, didPop
, didPushNext
等回调方法。
RouteAware 接口提供的主要回调方法:
didPopNext
:当前页面是目标页面,当另一个页面弹出时,触发这个回调。didPushNext
:当前页面被新页面覆盖时,触发这个回调。didPop
:当前页面被弹出时,触发这个回调。didPush
:当前页面被推入导航栈时,触发这个回调。
使用步骤
第一步:创建一个 RouteObserver
首先,你需要在应用中创建一个 RouteObserver
实例。通常会在 MaterialApp
或 CupertinoApp
的 navigatorObservers
参数中进行配置。
import 'package:flutter/material.dart';
// 创建 RouteObserver 实例
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
navigatorObservers: [routeObserver], // 配置 RouteObserver
home: VmTestPage1(),
);
}
}
第二步:创建一个 RouteAware
的 StatefulWidget
接下来,你需要在希望监听的页面(或 Widget)中实现 RouteAware
。RouteAware
是一个接口,允许对象感知其路由的变化。然后,将这个对象注册到 RouteObserver
中。
import 'package:flutter/material.dart';
import 'package:your_app_name/route_observer.dart';
class VmTestPage2 extends StatefulWidget {
@override
_VmTestPage2State createState() => _VmTestPage2State();
}
class _VmTestPage2State extends State<VmTestPage2> with RouteAware {
@override
void initState() {
super.initState();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
// 注册到 RouteObserver 中
routeObserver.subscribe(this, ModalRoute.of(context)!);
}
@override
void dispose() {
// 注销 RouteObserver
routeObserver.unsubscribe(this);
super.dispose();
}
// 页面可见时调用
@override
void didPush() {
super.didPush();
print('VmTestPage2 is visible');
}
// 页面从别的页面返回时调用
@override
void didPopNext() {
super.didPopNext();
print('VmTestPage2 has returned from another page');
}
// 页面被覆盖时调用
@override
void didPop() {
super.didPop();
print('VmTestPage2 is being popped');
}
// 页面被重新显示时调用
@override
void didPushNext() {
super.didPushNext();
print('Another page was pushed on top of VmTestPage2');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('VmTestPage2'),
),
body: Center(
child: Text('This is VmTestPage2'),
),
);
}
}
关键方法解释:
didPush()
:当页面被推到导航栈时(即页面可见时)调用。didPopNext()
:当页面从下一个页面返回时调用(即该页面重新可见时)。didPop()
:当页面从导航栈中弹出时调用。didPushNext()
:当下一个页面推到该页面之上时调用(即该页面被覆盖时)。
第三步:在需要监听的地方使用 RouteObserver
通过以上步骤,你已经实现了对 VmTestPage2
的路由事件监听。这种方式在需要了解页面的进入、离开、重新进入等生命周期时非常有用。