最近开发 Flutter 项目学到一个非常好用的方法或者说函数 WidgetsBinding.instance.addPostFrameCallback
。它的作用很简单,当前帧绘制完后执行 addPostFrameCallback
的回调函数,这么说可能有点抽象,我具体展开聊聊。
使用场景
Flutter 中的界面组件(控件)只要一帧就能绘制渲染在屏幕上,当然,这一帧 Flutter 做了很多事,包括 Build、Layout 和 Painting 阶段。而 addPostFrameCallback
就是在每一帧绘制完成后再回调执行一些自己的方法。这个机制的使用场景非常多。
比如组件渲染完后做一些操作,像开启动画、弹出对话框 Dialog、获取组件 Widget 的大小和位置。或者使用 addPostFrameCallback
延迟加载数据,确保界面渲染完才加载数据,避免出现 UI 阻塞。还有,在界面组件渲染完成后,请求接口获取数据,动态添加组件等等。总之,当你需要在组件首次渲染完成后执行某些操作时,都可以使用它。
如何使用
最常见就是在生命周期 init()
初始化中使用,因为 init()
只会在组件首次渲染执行,是很特殊的函数,而在 initState
中使用 WidgetsBinding.instance.addPostFrameCallback
,也就说明我们在组件首次渲染完成后执行回调函数。
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
print("initState: Frame has been rendered");
});
}
我们在 initState
中注册 WidgetsBinding.instance.addPostFrameCallback
,这个注册操作是在方法 initState
中执行的,但回调函数本身将在当前帧的绘制完成执行。
其次我们还能在 build
方法中的使用 addPostFrameCallback
。这表明我们的回调函数会在每次 Widget 重新构建时执行,回调函数会多次渲染执行,而不是像 init()
中的只执行一次。
我这里举个例子,像 setState
会触发 build 方法,如果我们在 build 中使用 addPostFrameCallback
,这样每次 build 后都会执行回调函数。
class _FrameCallbackPageState extends State<FrameCallbackPage> {
int _counter = 0;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
print("initState: Frame has been rendered");
});
}
void _incrementCounter() {
setState(() {
_counter++;
});
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
print("setState: Frame has been rendered");
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('WidgetsBinding Example')),
body: Center(
child: Text("Counter:$_counter")
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
上面代码运行后再点击按钮,打印日志:
flutter: initState: Frame has been rendered
flutter: setState: Frame has been rendered
flutter: setState: Frame has been rendered
OK,希望以上分享能帮到你。
本文由老郭种树原创,转载请注明:https://guozh.net/add-post-frame-callback/