我想能够运行函数一旦一个小部件已经完成构建/加载,但我不确定如何。
我目前的用例是检查用户是否通过身份验证,如果没有,则重定向到登录视图。我不想检查之前,并推动登录视图或主视图,它需要发生后,主视图已加载。
有什么我可以用的吗?
我想能够运行函数一旦一个小部件已经完成构建/加载,但我不确定如何。
我目前的用例是检查用户是否通过身份验证,如果没有,则重定向到登录视图。我不想检查之前,并推动登录视图或主视图,它需要发生后,主视图已加载。
有什么我可以用的吗?
当前回答
在flutter版本1.14.6中,Dart版本28。
你只需要将你想要在构建方法之后发生的所有事情捆绑到一个单独的方法或函数中。
@override
void initState() {
super.initState();
print('hello girl');
WidgetsBinding.instance
.addPostFrameCallback((_) => afterLayoutWidgetBuild());
}
其他回答
有三种可能的方法:
1) WidgetsBinding.instance.addPostFrameCallback((_) => yourFunc(context));
2) Future.delayed(Duration.zero, () => yourFunc(context));
3) Timer.run(() => yourFunc(context));
至于context,在渲染完所有的小部件后,我需要在Scaffold.of(context)中使用它。
但在我看来,最好的办法是:
void main() async {
WidgetsFlutterBinding.ensureInitialized(); //all widgets are rendered here
await yourFunc();
runApp( MyApp() );
}
扑动1.2 -飞镖2.2
根据官方的指导方针和来源,如果你想确定你的布局的最后一帧也被绘制,你可以这样写,例如:
import 'package:flutter/scheduler.dart';
void initState() {
super.initState();
if (SchedulerBinding.instance.schedulerPhase == SchedulerPhase.persistentCallbacks) {
SchedulerBinding.instance.addPostFrameCallback((_) => yourFunction(context));
}
}
如果你不想使用WidgetsBinding或SchedulerBinding:
使用Future或Timer(简单) Future<void> _runsAfterBuild() async { //此代码在build… } @override 小部件构建(BuildContext上下文){ 未来(_runsAfterBuild);// <——使用Future或Timer 返回容器(); } 等待一个虚拟的未来 Future<void> _runsAfterBuild() async { 等待未来((){});// <——虚拟等待 //此代码在build… } @override 小部件构建(BuildContext上下文){ _runsAfterBuild (); 返回容器(); }
我的英语很差 原谅我
import 'package:flutter/material.dart';
class TestBox extends StatefulWidget {
final Color color;
final Duration delay;
const TestBox({
Key? key,
this.color = Colors.red,
this.delay = const Duration(seconds: 5),
}) : super(key: key);
@override
_TestBoxState createState() => _TestBoxState();
}
class _TestBoxState extends State<TestBox> {
String? label;
@override
void initState() {
initialMembers();
super.initState();
}
void initialMembers() async {
label = await fetchLabel();
if (mounted) setState(() {});
/// don't worry
/// if `(!mounted)`, means wen `build` calld
/// the label already has the newest value
}
Future<String> fetchLabel() async {
await Future.delayed(widget.delay);
print('fetchLabel call');
return 'from fetchLabel()';
}
@override
Widget build(BuildContext context) {
return AnimatedContainer(
margin: EdgeInsets.symmetric(vertical: 12),
duration: Duration(milliseconds: 500),
width: 220,
height: 120,
color: label == null ? Colors.white : widget.color,
child: Center(
child: Text(label ?? 'fetching...'),
),
);
}
}
Column(
children: [
TestBox(
delay: Duration(seconds: 1),
color: Colors.green,
),
TestBox(
delay: Duration(seconds: 3),
color: Colors.yellow,
),
TestBox(
delay: Duration(seconds: 5),
color: Colors.red,
),
],
),
最好的方法是,
1. WidgetsBinding
WidgetsBinding.instance.addPostFrameCallback((_) {
print("WidgetsBinding");
});
2. SchedulerBinding
SchedulerBinding.instance.addPostFrameCallback((_) {
print("SchedulerBinding");
});
它可以在initState内部调用,两者都只会在构建小部件完成渲染后调用一次。
@override
void initState() {
// TODO: implement initState
super.initState();
print("initState");
WidgetsBinding.instance.addPostFrameCallback((_) {
print("WidgetsBinding");
});
SchedulerBinding.instance.addPostFrameCallback((_) {
print("SchedulerBinding");
});
}
以上两个代码的工作原理是一样的,因为它们都使用了类似的绑定框架。 要了解差异,请查看下面的链接。
https://medium.com/flutterworld/flutter-schedulerbinding-vs-widgetsbinding-149c71cb607f