Я хочу обратиться к следующему сценарию:
Экран / виджет отображается (нажат).
Этот экран должен:
- выполнить долгое задание (запрос) при первом его создании
- показать загрузку при выполнении задачи (запрос)
- при необходимости отобразить диалоговое окно с ошибкой (неудачный запрос)
- обновить список соответствующим образом после завершения задачи
- есть внешний триггер для обновления и перезапуска длинной задачи (запрос данных снова + загрузка и оповещения включены)
--------------------------
Я пришел к выводу, что вы не можете иметь такое поведение без:
- механизм задержки для отображения диалога об ошибках (addPostFrameCallback или Future.delayed)
- механизм состояния для обработки поведения компонента (начальная / загрузка / не загрузка / завершена)
Стоит отметить, что флаттер для меня новый, и мне может не хватать важной информации о фреймворке.
--------------------------
Вот причины для приведенных выше выводов.
Ограничение диалогового окна ошибки:
- из метода сборки вы не можете отобразить диалоговое окно, потому что вам нужно сначала вернуть виджет (учитывая, например, что задача не выполнена, вам нужно показать диалоговое окно); в противном случае появится сообщение об ошибке
// ...
// flutter: setState () или markNeedsBuild () вызывается во время сборки.
// flutter: этот виджет Overlay нельзя пометить как необходимый для сборки, потому что фреймворк уже находится в
// setState () или markNeedstoBuild ()
// ...
если вы выполнили задачу до того, как метод сборки потерпит неудачу, у вас снова будет та же ошибка
// ...
// flutter: inheritFromWidgetOfExactType (_LocalizationsScope) или inheritFromElement () был вызван ранее
// flutter: _VacationsViewState.initState () завершено.
// ...
задача не может быть запущена методом построения, поскольку этот метод вызывается много раз.
Ограничение индикатора состояния:
- после того, как компонент виджета был создан, если задача запускалась для повторного выполнения, у компонента не будет никакой возможности узнать, что ему нужно отображать индикатор загрузки, если у него нет этого механизма состояния. Этот механизм состояний подразумевает вызов setState или использование построителей потоков (в зависимости от состояния).
--------------------------
Дополнительные фрагменты, иллюстрирующие следующие ситуации:
// using FutureBuilder
Widget build(BuildContext context) {
return FutureBuilder(
future: someFuture,
builder: (BuildContext context, AsyncSnapshot snapshot) {
// Here we need to display loading while task is not finished and a dialog if it fails
// dialog needs to be performed with a delay
// triggering again the build will need to have a setState called to “reload”
});
}
// using StreamBuilder
Widget build(BuildContext context) {
return StreamBuilder<void>(
stream: status,
builder: (BuildContext context, AsyncSnapshot<void> status) {
// status can represent states (loading/finished/… )
// dialog needs to be displayed with a delay in case the error the current state
});
}
--------------------------
Достигнут окончательный компромисс:
- использовать некоторый механизм состояний с дескриптором состояния и, возможно, потоком или использовать setState напрямую
- использовать механизм задержки для диалогов
--------------------------