接着完善上一篇内容,上一篇我们是能监听到初次进入路由页面节点,往往还想监听从当前路由跳转到其他路由后,再返回到当前路由页面,上一篇内容就无法满足当前需求了,不过我们完全可以按照上一篇的原理实现这个需求。
直接上代码
- /// @author bawomingtian
- /// @date 2023/10/16
- /// @desc 通过监听路由入场动画完成,判断路由完全进入,可以用来优化在进场动画执行过程中
- /// 异步请求数据刷新界面,导致进场动画卡顿的问题
- class AsyncState<T extends StatefulWidget> extends State<T> with RouteAwareMixin implements NavigatorObserver {
- Completer<bool> _resumeCompleter = Completer();
-
- @override
- void didChangeDependencies() {
- ModalRoute.of(context)!.controller?.addStatusListener((status) {
- if (status == AnimationStatus.completed) {
- _resumeCompleter.complete(true);
- initAsyncLoad();
- }
- });
- super.didChangeDependencies();
- }
-
- @override
- void initState() {
- super.initState();
- Navigator.observer.add(this);
- }
-
- @override
- void dispose() {
- Navigator.observer.remove(this);
- super.dispose();
- }
-
- Future
asyncWaitResume(Future future) async { - var value = await future;
- await _resumeCompleter.future;
- return value;
- }
-
- void initAsyncLoad() {}
-
- void resumeAsyncLoad() {}
-
- @override
- Widget build(BuildContext context) {
- return const SizedBox();
- }
-
- @override
- void didPush(Route route, Route? previousRoute) {
- if (route is ModalRoute) {
- route.controller?.addStatusListener((status) {
- if (status == AnimationStatus.dismissed) {
- resumeAsyncLoad();
- }
- });
- }
- super.didPush(route, previousRoute);
- }
-
- }
-
- mixin RouteAwareMixin {
- void didPop(Route route, Route? previousRoute) {}
-
- void didPush(Route route, Route? previousRoute) {}
-
- void didRemove(Route route, Route? previousRoute) {}
-
- void didReplace({Route? newRoute, Route? oldRoute}) {}
-
- void didStartUserGesture(Route route, Route? previousRoute) {}
-
- void didStopUserGesture() {}
-
- @override
- NavigatorState? get navigator => throw UnimplementedError();
- }
方法 initAsyncLoad 为第一次进入路由页面回调
方法 resumeAsyncLoad 为从其他路由返回到该路由页面回调
有了这两个方法,我们就可以异步请求一些耗时或者频繁多次调用的接口了,不用担心影响路由跳转动画