前面部分,已经介绍过了,组件的构建渲染=> 传送门api
在咱们原生Android(或者IOS)开发中,不少是否要在对应的生命周期作一些事件,例如App从后台进入前台,从前台退入后台(或被遮盖),以及须要在确保UI绘制后作一些处理,这在咱们原生开发中很容易作到,那么在Flutter中须要怎么去作呢?安全
很简单,给WidgetsBinding设置Observeride
class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver{
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);//添加观察者
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
print("lifeChanged $state");
}
@override
void dispose() {
super.dispose();
WidgetsBinding.instance.removeObserver(this);//销毁
}
@override
Widget build(BuildContext context) {
return Container();
}
}
复制代码
经过以上代码,咱们能够看到只要给WidgetsBinding的单例对象添加WidgetsBindingObserver,而后此类粘合(with)WidgetsBindingObserver抽象类,在初始化State的时候给WidgetsBinding设置Observer为当前类,并在销毁的时候移除Observer,此时咱们的State就具有WidgetsBindingObserver的回调了。post
(关于with的做用读者可自行搜索相关关键字mixin、with)。字体
咱们看看WidgetsBindingObserver中具体有哪些回调:ui
abstract class WidgetsBindingObserver {
//路由弹出Future
Future<bool> didPopRoute() => Future<bool>.value(false);
//新的路由Future
Future<bool> didPushRoute(String route) => Future<bool>.value(false);
//系统窗口相关改变回调,例如旋转
void didChangeMetrics() { }
//文字系数变化
void didChangeTextScaleFactor() { }
//本地化语言变化
void didChangeLocales(List<Locale> locale) { }
//生命周期变化
void didChangeAppLifecycleState(AppLifecycleState state) { }
//低内存回调
void didHaveMemoryPressure() { }
//当前系统改变了一些访问性活动的回调
void didChangeAccessibilityFeatures() {}
}
复制代码
能够看到,常见的屏幕、字体、语言等变化都会经过此类实现进行回调,这里咱们关注生命周期的变化方法didChangeAppLifecycleStatethis
void didChangeAppLifecycleState(AppLifecycleState state) { }
spa
这个方法有一个参数类型为AppLifecycleState的枚举类,咱们能够根据它的状态来处理咱们的一些任务code
enum AppLifecycleState {
resumed,
inactive,
paused,
suspending,
}
复制代码
Flutter回调的生命周期与Android基本上差很少,这里说一下回调比较特别的地方。server
以Android为例,当咱们Activity建立的时候,流程是这样的:
建立期:onCreate -> onStart -> onResume
进入后台: onPause -> onStop
从后台恢复:onRestart->onResume
而在Flutter中这整个流程是:
建立期: initState
进入后台: inactive -> paused
从后台恢复: inactive -> resumed
对比发现,在咱们页面建立的时候不会触发生命周期回调(didChangeAppLifecycleState),而在进入后台和从后台恢复的时候都会先调用inactive(可见,不可响应)而后调用paused(完全不可见)或者resumed(可见并可操做)。至于挂起(suspending)的回调,笔者暂时还不知道怎样才会触发。
Tips:当生命周期可交互时(resumed)才开始绘制Frame,生命周期变为不可交互时(paused、suspending)会中止绘制Frame,这个后面分析Flutter启动时会介绍。
有的时候咱们须要在Widget渲染以后作一些安全的操做,在Android中能够经过View.post()插入消息队列,这样能够保证在组件渲染后进行操做,那么Flutter中有没有这样的API呢?固然有啦..
仍是咱们的WidgetsBinding
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_){
print("Frame has been rendered");
});
}
复制代码
经过addPostFrameCallback能够作一些安全的操做,在有些时候是颇有用的,它会在当前Frame绘制完后进行回调,并只会回调一次,若是要再次监听须要再设置。
WidgetsBinding.instance.addPersistentFrameCallback((_){
print("Frame has been rendered");
});
复制代码
这个api在每次绘制Frame结束后都会回调,咱们能够利用它作一些帧率检测。
这些都是比较经常使用的,更多有用好玩的api得你们本身去发现。