setState(), вызываемый после dispose()

Когда я нажимаю на поднятую кнопку, появляется всплывающая подсказка. Теперь, если я жду, как 5 секунд, а затем подтвержу время, когда эта ошибка возникнет, setState(), вызванный после dispose()

Я буквально вижу в консоли, как flutter обновляет родительские виджеты, но почему? - Я ничего не делаю - я просто жду 5 секунд!? Этот пример будет работать в обычном проекте, но в моем проекте, который является более сложным, он не будет работать, потому что флаттер обновляет состояния, пока я жду... Что я не так? Кто-нибудь догадывается, что это может быть, что флаттер обновляется случайно в моем более сложном проекте, а не в простом проекте?

[UPDATE] Я проверил, что он обновляется с уровня, на котором расположены мои TabBar и TabBarView. Может ли это что-то сделать с помощью " с TickerProviderStateMixin ", который мне нужен для tabbarview? Может ли это быть причиной того, что приложение обновляется регулярно и случайным образом?

 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();
      }
    );
  }
}

Ответы

Ответ 1

Просто проверьте логическое свойство, 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);
    }
  }
}

Ответ 2

Если это ожидаемое поведение, которое Future завершает, когда виджет уже удален, вы можете использовать

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

Ответ 3

Попробуй это

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

Ответ 4

Просто напишите одну строку перед setState()

 if (!mounted) return;

а потом

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

Ответ 5

mounted свойство StatefulWidget отслеживает, отображается ли ваш виджет. Для проверки монтируется каждый раз, решит вопрос.

Или даже более чистый подход Переопределить метод setState в вашем классе Stateless setState.

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