我想能够运行函数一旦一个小部件已经完成构建/加载,但我不确定如何。
我目前的用例是检查用户是否通过身份验证,如果没有,则重定向到登录视图。我不想检查之前,并推动登录视图或主视图,它需要发生后,主视图已加载。
有什么我可以用的吗?
我想能够运行函数一旦一个小部件已经完成构建/加载,但我不确定如何。
我目前的用例是检查用户是否通过身份验证,如果没有,则重定向到登录视图。我不想检查之前,并推动登录视图或主视图,它需要发生后,主视图已加载。
有什么我可以用的吗?
当前回答
我有一个有状态的小部件,我使用html_editor_enhanced插件小部件。这是在其中设置初始消息的唯一方法。
class _SendChatMessageState extends State<SendChatMessage> {
final _htmlController = HtmlEditorController();
@override
void initState() {
super.initState();
Future.delayed(const Duration(seconds: 3), () {
_htmlController.setText(widget.chatMessage.message ?? '');
});
}
我尝试了addPostFrameCallback,但它不起作用,因为JavaScript生成异常“HTML编辑器仍在加载,请在评估此JS之前等待…”
其他回答
你可以用
https://github.com/slightfoot/flutter_after_layout
它只在布局完成后执行一次函数。 或者只是看看它的实现,并将其添加到你的代码中:-)
基本上就是
void initState() {
super.initState();
WidgetsBinding.instance
.addPostFrameCallback((_) => yourFunction(context));
}
如果你正在寻找ReactNative的componentDidMount等效,Flutter有它。事情没那么简单,但原理是一样的。在Flutter中,小部件不直接处理它们的事件。相反,它们使用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);
}
状态。一旦屏幕完成布局渲染,initState将立即被调用。如果处于调试模式,即使在热重载时也不会再次调用,直到显式地达到这样做的时间。
我有一个有状态的小部件,我使用html_editor_enhanced插件小部件。这是在其中设置初始消息的唯一方法。
class _SendChatMessageState extends State<SendChatMessage> {
final _htmlController = HtmlEditorController();
@override
void initState() {
super.initState();
Future.delayed(const Duration(seconds: 3), () {
_htmlController.setText(widget.chatMessage.message ?? '');
});
}
我尝试了addPostFrameCallback,但它不起作用,因为JavaScript生成异常“HTML编辑器仍在加载,请在评估此JS之前等待…”
我的英语很差 原谅我
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,
),
],
),
更新:Flutter v1.8.4
上述两个代码现在都在工作:
工作:
WidgetsBinding.instance
.addPostFrameCallback((_) => yourFunction(context));
工作
import 'package:flutter/scheduler.dart';
SchedulerBinding.instance.addPostFrameCallback((_) => yourFunction(context));