flutter页面在A->B后,A页面不能更新页面,但是有没有类似Android 的onResume,onPause方法回调,只能自己创建
通过NavigatorObserver监听页面push与pop等操作
通过WidgetsBindingObserver监听前后台切换
具体看下代码
class RouteInfo {
StringresumeRouteName;
StringpauseRouteName;
RouteInfo({this.resumeRouteName, this.pauseRouteName});
}
class CustomNavigatorObserverextends NavigatorObserver
with WidgetsBindingObserver {
static CustomNavigatorObserver_instance;
LiveData_liveData =LiveData();
LiveDataget liveData =>_liveData;
String_resumeRouteName;
factory CustomNavigatorObserver.getInstance() {
if (_instance ==null) {
_instance =CustomNavigatorObserver._newInstance();
}
return _instance;
}
CustomNavigatorObserver._newInstance() {
WidgetsBinding.instance.addObserver(this);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
///从后台切回
if (state == AppLifecycleState.resumed) {
RouteInfo routeInfo =RouteInfo(
resumeRouteName:_resumeRouteName, pauseRouteName:null);
_liveData.data = routeInfo;
}else
///切到后台
if (state == AppLifecycleState.paused) {
RouteInfo routeInfo =RouteInfo(
resumeRouteName:null, pauseRouteName:_resumeRouteName);
_liveData.data = routeInfo;
}
}
@override
void didReplace({Route newRoute, Route oldRoute}) {
super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
print("replace ${newRoute?.settings?.name},${oldRoute?.settings?.name}");
_resumeRouteName = newRoute?.settings?.name;
RouteInfo routeInfo =RouteInfo(
resumeRouteName:_resumeRouteName,
pauseRouteName: oldRoute?.settings?.name);
_liveData.data = routeInfo;
}
///pushNamedAndRemoveUntil route 是要进入的页面,previousRoute是null
///pushNamedAndRemoveUntil('/screen4',ModalRoute.withName('/screen1'));
///route是 screen4 ,previousRoute一直是 screen1 会调多次 所以直接currentRoute:null
@override
void didRemove(Route route, Route previousRoute) {
super.didRemove(route, previousRoute);
print("remove ${route?.settings?.name},${previousRoute?.settings?.name}");
_resumeRouteName = route?.settings?.name;
RouteInfo routeInfo =
RouteInfo(resumeRouteName:null, pauseRouteName:_resumeRouteName);
_liveData.data = routeInfo;
}
@override
void didPop(Route route, Route previousRoute) {
super.didPop(route, previousRoute);
print("pop ${route?.settings?.name},${previousRoute?.settings?.name}");
_resumeRouteName = previousRoute?.settings?.name;
RouteInfo routeInfo =RouteInfo(
resumeRouteName:_resumeRouteName,
pauseRouteName: route?.settings?.name);
_liveData.data = routeInfo;
}
@override
void didPush(Route route, Route previousRoute) {
super.didPush(route, previousRoute);
print("push ${route?.settings?.name},${previousRoute?.settings?.name}");
_resumeRouteName = route?.settings?.name;
RouteInfo routeInfo =RouteInfo(
resumeRouteName:_resumeRouteName,
pauseRouteName: previousRoute?.settings?.name);
_liveData.data = routeInfo;
}
}
LiveData是自己写的事件通知器,可以换成其他的通知,类似ValueNotifier都可以
在入口APP注册
因为是根据name判断的,添加routes,其他人没有使用,没关系,只要在进入我们自己的页面使用就可以监听到
基类State
///
/// 添加生命周期及监听,使用pushNamed的方式才可以
///
abstract class LifecycleStateextends State{
Event_currentEvent;
boolisActive() {
return _currentEvent == Event.ON_INIT ||_currentEvent == Event.ON_RESUME;
}
List_listeners = [];
void addListener(LifecycleCallback lifecycleCallback) {
if (lifecycleCallback ==null) {
return;
}
_listeners.add(lifecycleCallback);
if (_currentEvent !=null) {
lifecycleCallback.call(_currentEvent);
}
}
LiveDataCallBack_liveDataCallBack;
void _liveCallback(RouteInfo routeInfo){
if (routeInfo.resumeRouteName ==routeName) {
resume();
}
if (routeInfo.pauseRouteName ==routeName) {
pause();
}
}
@override
void initState() {
super.initState();
_liveDataCallBack =LiveDataCallBack(callBack: _liveCallback, state:null,stick:false);
CustomNavigatorObserver.getInstance().liveData.addListeners(_liveDataCallBack);
_currentEvent = Event.ON_INIT;
_dispatchChangeEvent();
Future.delayed(Duration(milliseconds:300),(){
resume();
});
}
@override
void dispose() {
CustomNavigatorObserver.getInstance().liveData.removeListeners(_liveDataCallBack);
_currentEvent = Event.ON_DISPOSE;
_dispatchChangeEvent();
super.dispose();
_currentEvent =null;
_listeners =null;
}
void resume() {
_currentEvent = Event.ON_RESUME;
_dispatchChangeEvent();
}
///可能执行多次
///在当前页面调用pushNamedAndRemoveUntil,当前页调两次
void pause() {
_currentEvent = Event.ON_PAUSE;
_dispatchChangeEvent();
}
void _dispatchChangeEvent() {
_listeners.forEach((element) {
element.call(_currentEvent);
});
}
@protected
Stringget routeName;
}
主要是CustomNavigatorObserver相关的加上就行,其他是LiveData添加的页面状态回调,
LiveData是类似Android的LiveData根据页面在可刷新是回调.LiveData地址
//////更新////////// 将CustomNavigatorObserver回调封装起来,并添加在外部间接操作的回调的方法,主要可以控制PageView的页面切换
typedef RouteInfoCallBack =void Function(RouteInfo);
class LiveDataCallBackWrapperextends LiveDataCallBack {
LiveDataCallBackWrapper(RouteInfoCallBack callBack)
:super(state:null, stick:false, callBack: callBack);
@override
intget hashCode =>callBack.hashCode;
@override
booloperator ==(Object other) {
if(other ==null){
return false;
}
if(otheris! LiveDataCallBackWrapper){
return false;
}
LiveDataCallBackWrapper wrapper = other;
return callBack == wrapper.callBack;
}
}
class CustomNavigatorObserverextends NavigatorObserver
with WidgetsBindingObserver {
static CustomNavigatorObserver_instance;
LiveData_liveData =LiveData();
void addRouteListener(RouteInfoCallBack dataCallBack) {
_liveData.addListeners(LiveDataCallBackWrapper(dataCallBack));
}
void removeRouteListener(RouteInfoCallBack dataCallBack) {
_liveData.removeListeners(LiveDataCallBackWrapper(dataCallBack));
}
String_resumeRouteName;
void sendRouteName(String resumeRouteName, String pauseRouteName) {
_liveData.data =RouteInfo(
resumeRouteName: resumeRouteName, pauseRouteName: pauseRouteName);
}
}