Проблема

Большинству Flutter-приложений приходится выполнять задачи, занимающие несколько секунд — загрузка данных из API, отправка файла или обработка платежа. В это время пользователь видит застывший экран без каких-либо признаков того, что что-то происходит. Он нажимает кнопку повторно, вызывает дублирующие запросы или решает, что приложение зависло.

Стандартное решение — вручную управлять состоянием загрузки: переключить флаг, показать спиннер, дождаться завершения future, скрыть спиннер, а затем обработать результат или ошибку. Эта логика дублируется на десятках экранов с мелкими различиями каждый раз.

Типичные проблемы:

  • Повторяющийся шаблонный код управления состоянием загрузки на каждом экране
  • Повторные нажатия пользователей из-за отсутствия визуальной обратной связи
  • Закрытые диалоги, которые оставляют «осиротевшие» future, продолжающие работу в фоне
  • Непоследовательная обработка ошибок — одни экраны перехватывают исключения, другие падают молча

Как flutter_future_progress_dialog решает эту задачу

flutter_future_progress_dialog заменяет весь этот шаблонный код одним вызовом функции. Передайте асинхронную задачу — пакет покажет незакрываемый диалог прогресса, дождётся результата, закроет диалог и вернёт типобезопасный результат: Success со значением или Failure с ошибкой.

Обработка ошибок встроена в тип результата, поэтому вы никогда не забудете перехватить исключение.

Возможности

  • Material-диалогshowProgressDialog отображает стандартный круговой индикатор прогресса в стиле Material
  • Cupertino-диалогshowCupertinoProgressDialog показывает индикатор активности в стиле iOS
  • Адаптивный диалогshowAdaptiveProgressDialog автоматически выбирает стиль, соответствующий текущей платформе
  • Свой интерфейс диалога — передайте builder, чтобы заменить стандартный индикатор любым виджетом
  • Типобезопасные результатыProgressDialogResult<T> — sealed-класс с вариантами Success и Failure, поддерживающий pattern matching и удобные методы unwrap() и map()
  • Перехват ошибокFailure содержит объект ошибки и трассировку стека

Сценарии использования

Обработка платежей

Экран оформления заказа вызывает API платёжного шлюза. Без диалога прогресса пользователи нажимают «Оплатить» повторно, когда ничего не происходит, вызывая двойные списания. С showProgressDialog диалог остаётся на экране и блокирует взаимодействие до ответа шлюза, а затем pattern matching результата позволяет перейти на экран подтверждения или ошибки.

Загрузка файлов

Сканер документов отправляет изображения на сервер. Загрузка может занять несколько секунд на медленном соединении. Если обернуть загрузку в showAdaptiveProgressDialog, пользователь сразу получает визуальную обратную связь, а диалог соответствует стилю платформы — Material на Android, Cupertino на iOS.

Отправка форм

Многошаговая форма отправляет данные на сервер на финальном этапе. Диалог прогресса предотвращает повторную отправку и даёт понятный результат Success/Failure, по которому легко решить, что показывать — экран успеха или сообщение об ошибке прямо в форме.

Фоновая синхронизация данных

CRM-приложение синхронизирует локальные изменения с удалённым сервером. Собственный builder может показать брендированную анимацию загрузки вместо стандартного спиннера, сохраняя единый стиль приложения.

Начало работы

Установите пакет:

flutter pub add flutter_future_progress_dialog

Затем вызовите showProgressDialog с вашей асинхронной задачей:

final result = await showProgressDialog(
  context: context,
  future: () => fetchData(),
);

switch (result) {
  case Success(:final value):
    // Используйте значение
  case Failure(:final error):
    // Обработайте ошибку
}

Доступны три функции диалога: showProgressDialog (Material), showCupertinoProgressDialog (Cupertino) и showAdaptiveProgressDialog (автоматический выбор платформы). Все принимают необязательный параметр builder для своего интерфейса.

Полный рабочий пример доступен в директории example.

Нет. Диалог по умолчанию незакрываемый, что предотвращает осиротевшие future и повторные отправки. Диалог закрывается автоматически после завершения асинхронной задачи.
Диалог закроется, а результат вернётся как Failure, содержащий ошибку и трассировку стека. Ваш код может использовать pattern matching для обработки ошибок без блоков try-catch.
Да. Используйте showProgressDialog для стиля Material, showCupertinoProgressDialog для стиля iOS или showAdaptiveProgressDialog для автоматического соответствия платформе.
Да. Передайте параметр builder в любую из трёх функций диалога, чтобы заменить стандартный индикатор прогресса на свой виджет — брендированную анимацию, текстовое сообщение или любой другой Flutter-виджет.
ProgressDialogResult<T> — это sealed-класс с двумя вариантами: Success<T>, содержащий возвращённое значение, и Failure<T>, содержащий ошибку и трассировку стека. Можно использовать pattern matching в Dart или удобные методы isSuccess, isError, unwrap() и map().