Flutter - 监视页面的切换(RouteObserver & RouteAware)

经常性的,我们需要监视页面的切换,用以在合适的时候对控件进行动画暂停或者资源释放。

举个栗子:
相机拍照是我们需要经常用到的功能,但是当我们在切换到相机配置页面时,需要暂停当前相机预览,这种情况下我们就需要监视页面的路由变化情况,又或者用户回到应用桌面,此时也需要对相机进行暂停,返回又恢复相机。

在这里主要关系到下面两个方面的:

  1. AppStateLifeRecycle - 今天我们不说这个;
  2. RouteAware

先看看RouteAware是如何定义的?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/// An interface for objects that are aware of their current [Route].
///
/// This is used with [RouteObserver] to make a widget aware of changes to the
/// [Navigator]'s session history.
abstract class RouteAware {
/// Called when the top route has been popped off, and the current route
/// shows up.
void didPopNext() { }

/// Called when the current route has been pushed.
void didPush() { }

/// Called when the current route has been popped off.
void didPop() { }

/// Called when a new route has been pushed, and the current route is no
/// longer visible.
void didPushNext() { }
}

上面提交到4个方法,分别都有什么用呢?
假如有3个页面,分别是A、B、C,跳转逻辑由A->B->C,而RouteAware使用with混淆在B中。

  • didPopNext:在C页面关闭后,B页面调起该方法;
  • didPush: 当由A打开B页面时,B页面调起该方法;
  • didPop: 当B页面关闭时,B页面调起该方法;
  • didPushNext: 当从B页面打开C页面时,该方法被调起。

如何使用?

  1. 使用with关键字在State类中使用,使用前在MaterialApp中定义一个RouteObserver对象。
    如下:
1
2
3
4
5
6
7
8
9
10
final RouteObserver<PageRoute> routeObserver = RouteObserver();

class MyApp extends StatelessWidget {
... \\此处省略一些代码

Widget _buildMaterialApp() => MaterialApp(
initialRoute: '/',
navigatorObservers: [routeObserver], //添加路由观察者
onGenerateRoute: _onGenerateRoute);
}
  1. 在B页面中混淆RouteAware, 并注册RouteObserver
    如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class B extends StatefulWidget {
B({Key key}) : super(key: key);
}

class BState extends State<B> with RouteAware {

@override
void didChangeDependencies() {
routeObserver.subscribe(this, ModalRoute.of(context)); //订阅
super.didChangeDependencies();
}

@override
void didPush() {
debugPrint("------> didPush");
super.didPush();
}

@override
void didPop() {
debugPrint("------> didPop");
super.didPop();
}

@override
void didPopNext() {
debugPrint("------> didPopNext");
super.didPopNext();
}

@override
void didPushNext() {
debugPrint("------> didPushNext");
super.didPushNext();
}

@override
void dispose() {
routeObserver.unsubscribe(this); //取消订阅
super.dispose();
}
}

总结 :

  1. 路由观察者添加订阅与取消订阅必须成对出现;
  2. 一些对象在使用后一定要记得及时释放资源。
坚持原创技术分享,您的支持将鼓励我继续创作!