Flutter:Widget构建完成后运行方法

时间:2018-03-24 15:36:02

标签: dart flutter

我希望能够在Widget完成构建/加载后运行函数,但我不确定如何。 我目前的用例是检查用户是否经过身份验证,如果没有,则重定向到登录视图。我不想在之前检查并推送登录视图或主视图,它需要在主视图加载后发生。 有什么我可以用来做这个吗?

9 个答案:

答案 0 :(得分:52)

您可以使用

https://github.com/slightfoot/flutter_after_layout

在布局完成后仅执行一次函数。 或者只是查看它的实现并将其添加到您的代码中: - )

基本上是

  void initState() {
    super.initState();
    WidgetsBinding.instance
        .addPostFrameCallback((_) => yourFunction(context));
  }

答案 1 :(得分:17)

更新:

提及的代码已不再有效:

  

不起作用:

const arr = [
  { first: 'Jane', last: 'Doe', x: 1 },
  { first: 'Jane1', last: 'Doe1', x: 2 },
  { first: 'Jane2', last: 'Doe2', x: 3 },
  { first: 'Jane3', last: 'Doe4', x: 4 }
];          

const result = arr.filter(o => o.x > 2).map(o => ({first: o.first, x: o.x}));

console.log(result);
  

工作代码:

WidgetsBinding.instance
        .addPostFrameCallback((_) => yourFunction(context));

答案 2 :(得分:9)

在Flutter 1.14.6版和Dart 28版中。

下面是对我有用的方法,您只需要将build方法之后想要发生的一切捆绑到单独的方法或函数中即可。

@override
void initState() {
super.initState();
print('hello girl');

WidgetsBinding.instance
    .addPostFrameCallback((_) => afterLayoutWidgetBuild());

}

答案 3 :(得分:4)

如果您正在寻找ReactNative的componentDidMount等效项,Flutter会提供。它不是那么简单,但是它以相同的方式工作。在Flutter中,Widget不直接处理其事件。取而代之的是,他们使用自己的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。如果您处于调试模式,则即使在热重载时也不会再被调用,直到明确地有时间这样做为止。

答案 4 :(得分:4)

最佳方法,

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

答案 5 :(得分:2)

Flutter 1.2-飞镖2.2

根据官方指南和sources,如果您想确定还绘制了布局的最后一帧,则可以编写例如:

import 'package:flutter/scheduler.dart';

void initState() {
   super.initState();
   if (SchedulerBinding.instance.schedulerPhase == SchedulerPhase.persistentCallbacks) {
        SchedulerBinding.instance.addPostFrameCallback((_) => yourFunction(context));
   }
}

答案 6 :(得分:1)

尝试SchedulerBinding,

 SchedulerBinding.instance
                .addPostFrameCallback((_) => setState(() {
              isDataFetched = true;
            }));

答案 7 :(得分:0)

如果您只想执行一次,那么就这样做,因为框架将为其创建的每个State对象恰好调用一次initState()方法。

 @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");
  }

答案 8 :(得分:-1)

另一种对我来说效果很好的解决方案是用 Future.delayed() 包装您想要调用的函数,如下所示:

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
       Future.delayed(Duration(seconds: 3), () => yourFunction());
    });
  }