61 lines
1.5 KiB
Dart
61 lines
1.5 KiB
Dart
// lib/common/route_aware_state.dart
|
||
import 'dart:async';
|
||
import 'package:flutter/widgets.dart';
|
||
import 'package:qhd_prevention/common/route_observer.dart';
|
||
|
||
/// 可复用的 RouteAware State 基类
|
||
/// 使用方式:class _MyPageState extends RouteAwareState<MyPage> { ... }
|
||
abstract class RouteAwareState<T extends StatefulWidget> extends State<T> with RouteAware {
|
||
/// 当页面真正可见(首次 push 或从上层 pop 返回)时会调用
|
||
@protected
|
||
FutureOr<void> onVisible();
|
||
|
||
@override
|
||
void didChangeDependencies() {
|
||
super.didChangeDependencies();
|
||
final ModalRoute? route = ModalRoute.of(context);
|
||
if (route is PageRoute) {
|
||
routeObserver.subscribe(this, route);
|
||
}
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
try {
|
||
routeObserver.unsubscribe(this);
|
||
} catch (_) {}
|
||
super.dispose();
|
||
}
|
||
|
||
@override
|
||
void didPush() {
|
||
// 页面被 push 到栈顶(首次展示)
|
||
_safeCallOnVisible();
|
||
}
|
||
|
||
@override
|
||
void didPopNext() {
|
||
// 从上层 pop 回到当前页面(页面再次可见)
|
||
_safeCallOnVisible();
|
||
}
|
||
|
||
@override
|
||
void didPushNext() {
|
||
// 当前页面被新的页面覆盖(不可见)
|
||
super.didPushNext();
|
||
}
|
||
|
||
void _safeCallOnVisible() {
|
||
// 延后到当前帧完成后执行,避免在 build 期间触发 setState 导致断言
|
||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||
if (!mounted) return;
|
||
try {
|
||
final r = onVisible();
|
||
if (r is Future) {
|
||
r.catchError((_) {});
|
||
}
|
||
} catch (_) {}
|
||
});
|
||
}
|
||
}
|