我希望小部件完成构建/加载后能够运行功能,但是我不确定如何运行。我当前的用例是检查用户是否已通过身份验证,如果未通过身份验证,则重定向到登录视图。我不想先检查并推送登录视图或主视图,它需要在主视图加载后进行。有什么我可以用来做的吗?
我希望小部件完成构建/加载后能够运行功能,但是我不确定如何运行。我当前的用例是检查用户是否已通过身份验证,如果未通过身份验证,则重定向到登录视图。我不想先检查并推送登录视图或主视图,它需要在主视图加载后进行。有什么我可以用来做的吗?
Answers:
你可以用
https://github.com/slightfoot/flutter_after_layout
布局完成后仅执行一次功能。或者只是看一下它的实现并将其添加到您的代码中:-)
基本上是
void initState() {
super.initState();
WidgetsBinding.instance
.addPostFrameCallback((_) => yourFunction(context));
}
WidgetsBinding.instance.addPostFrameCallback((_) => yourFunciton(context));
不再工作
initState
,例如。在中build
。
setState
在yourFunction
方法内调用以使其正常工作
更新: Flutter v1.8.4
上面提到的两个代码现在都可以正常工作:
加工:
WidgetsBinding.instance
.addPostFrameCallback((_) => yourFunction(context));
加工
import 'package:flutter/scheduler.dart';
SchedulerBinding.instance.addPostFrameCallback((_) => yourFunction(context));
NoSuchMethodError (NoSuchMethodError: The method 'addPostFrameCallback' was called on null. Receiver: null
有3种可能的方式:
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() );
}
根据官方指南和消息来源,如果您想确定还绘制了布局的最后一帧,则可以编写例如:
import 'package:flutter/scheduler.dart';
void initState() {
super.initState();
if (SchedulerBinding.instance.schedulerPhase == SchedulerPhase.persistentCallbacks) {
SchedulerBinding.instance.addPostFrameCallback((_) => yourFunction(context));
}
}
如果您正在寻找ReactNative的componentDidMount
等效产品,Flutter会提供。它不是那么简单,但是它以相同的方式工作。在Flutter中,Widget
s不直接处理其事件。相反,他们使用State
对象来执行此操作。
class MyWidget extends StatefulWidget{
@override
State<StatefulWidget> createState() => MyState(this);
Widget build(BuildContext context){...} //build layout here
void onLoad(BuildContext context){...} //callback when layout build done
}
class MyState extends State<MyWidget>{
MyWidget widget;
MyState(this.widget);
@override
Widget build(BuildContext context) => widget.build(context);
@override
void initState() => widget.onLoad(context);
}
State.initState
屏幕完成渲染布局后立即调用。如果您处于调试模式,则即使在热重载时也不会再被调用,直到明确地有时间这样做为止。
StatefulWidget
类来处理它的State
对象,StatelessWidget
但是我不建议这样做。我还没有发现任何问题,但是请先尝试在State
对象中实现所有内容
componentWillMount
在布局渲染之前完成。Flutter提供了更简单的解决方案。initState
如果我们知道如何正确进行数据提取和布局渲染,则足够了
在flutter版本1.14.6中,Dart版本28中。
以下是对我有用的方法,您只需要将build方法之后想要发生的一切捆绑到单独的方法或函数中即可。
@override
void initState() {
super.initState();
print('hello girl');
WidgetsBinding.instance
.addPostFrameCallback((_) => afterLayoutWidgetBuild());
}
最好的方法,
1. WidgetsBinding
WidgetsBinding.instance.addPostFrameCallback((_) {
print("WidgetsBinding");
});
2. WidgetsBinding
SchedulerBinding.instance.addPostFrameCallback((_) {
print("SchedulerBinding");
});
可以在内部调用它initState
,在用渲染完成Build小部件之后,两者都将仅被调用一次。
@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
尝试SchedulerBinding,
SchedulerBinding.instance
.addPostFrameCallback((_) => setState(() {
isDataFetched = true;
}));
如果您只想执行一次此操作,那么请执行此操作,因为框架将为initState()
它创建的每个State对象恰好调用一次方法。
@override
void initState() {
super.initState();
WidgetsBinding.instance
.addPostFrameCallback((_) => executeAfterBuildComplete(context));
}
如果您想一次又一次地执行此操作(例如在背面或导航到下一个屏幕等),则执行此操作,因为didChangeDependencies()
在此State对象的依赖项更改时调用。
例如,如果先前的调用build
引用了InheritedWidget
后来更改的,则框架将调用此方法以将该更改通知此对象。
之后也立即调用此方法initState
。BuildContext.dependOnInheritedWidgetOfExactType
从此方法调用是安全的。
@override
void didChangeDependencies() {
super.didChangeDependencies();
WidgetsBinding.instance
.addPostFrameCallback((_) => executeAfterBuildComplete(context));
}
这是您的回调功能
executeAfterBuildComplete([BuildContext context]){
print("Build Process Complete");
}
build
。可以多次调用构建。