在dispose()之后调用的setState()

时间:2018-03-17 17:57:28

标签: flutter

单击凸起按钮时,时间戳显示出来。现在,如果我等待5秒,然后确认将发生此错误的时间  在dispose()

之后调用的 setState()

我确实在控制台中看到flutter如何更新父窗口小部件,但为什么呢? - 我什么都不做 - 我等了5秒钟! 这个例子在普通项目中可以使用,但是在我的项目中,这个项目要复杂得多,因为在我等待的时候,颤动正在更新状态......我有什么问题?有没有人猜测在我更复杂的项目中是否可以随意更新,而不是在一个简单的项目中?

[UPDATE] 我检查它是从我的TabBar和TabBarView所在的级别更新。 是否必须对tabbarview所需的“ with TickerProviderStateMixin ”做些什么?可能是因为它导致应用程序定期和随机刷新?

 class DateTimeButton extends State<DateTimeButtonWidget> {
  DateTime selectedDate = new DateTime.now();

  Future initTimePicker() async {
    final TimeOfDay picked = await showTimePicker(
      context: context,
      initialTime: new TimeOfDay(hour: selectedDate.hour, minute: selectedDate.minute),
    );

    if (picked != null) {
      setState(() {
        selectedDate = new DateTime(selectedDate.year, selectedDate.month, selectedDate.day, picked.hour, picked.minute);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return new RaisedButton(
      child: new Text("${selectedDate.hour} ${selectedDate.minute}"),
      onPressed: () {
        initTimePicker();
      }
    );
  }
}

6 个答案:

答案 0 :(得分:37)

在调用mounted之前,只需检查窗口小部件的状态类的布尔属性setState()

if (this.mounted){
 setState((){
  //Your state change code goes here
 });
}

甚至更干净的方法 覆盖setState课程中的StatelfulWidget方法。

class DateTimeButton extends StatefulWidget{
   @override
   void setState(fn) {
    if(mounted){
      super.setState(fn);
    }
  }
}

答案 1 :(得分:8)

如果预期的行为是Future在窗口小部件已经处理完毕时完成,则可以使用

if (mounted) {
  setState(() {
    selectedDate = new DateTime(selectedDate.year, selectedDate.month, selectedDate.day, picked.hour, picked.minute);
  });
}

答案 2 :(得分:3)

我遇到了同样的问题,并且解决了更改initState()上的超级构造函数调用顺序的问题:

代码错误:

@override
  void initState() {
    foo_bar(); // in foo_bar i call setState();
    super.initState(); // state initialization after foo_bar()
  }

正确的代码:

@override
  void initState() {
    super.initState();
    foo_bar(); // first call super constructor then foo_bar that contains setState() call
  }

答案 3 :(得分:0)

试试这个

Widget build(BuildContext context) {
    return new RaisedButton(
        child: new Text("${selectedDate.hour} ${selectedDate.minute}"),
        onPressed: () async {
            await initTimePicker();
        }
    );
}

答案 4 :(得分:0)

只需在setState()前写一行

 if (!mounted) return;

然后

setState(() {
      //Your code
    });

答案 5 :(得分:0)

已安装

// First Update data 

if (!mounted) { 
      return;
 }
setState(() { }