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