Как реализовать обратный отсчёт в showDialog?

Как реализовать обратный отсчёт от 10 до 1 в showDialog?

Я пытался много раз, но увы – не вышло.


Ответы (1 шт):

Автор решения: Хуршид Собиров

Чтобы обеспечить обновление UI внутри диалога без необходимости создавать отдельный StatefulWidget, используется StatefulBuilder. Это особенно полезно в случаях, когда состояние нужно менять только внутри диалога.

Вот пример:

import 'dart:async';
import 'package:flutter/material.dart';

class CountdownDialogExample extends StatelessWidget {
  const CountdownDialogExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Обратный отсчёт в диалоге')),
      body: Center(
        child: ElevatedButton(
          onPressed: () => showCountdownDialog(context),
          child: const Text('Показать диалог'),
        ),
      ),
    );
  }

  void showCountdownDialog(BuildContext context) {
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) {
        int counter = 10;
        Timer? timer;

        return StatefulBuilder(
          builder: (context, setState) {
            void startCountdown() {
              timer = Timer.periodic(const Duration(seconds: 1), (timer) {
                if (counter > 1) {
                  setState(() => counter--);
                } else {
                  timer.cancel();
                  Navigator.of(context).pop(); // Закрыть диалог после окончания
                }
              });
            }

            if (timer == null) startCountdown();

            return AlertDialog(
              title: const Text('Обратный отсчёт'),
              content: Text('$counter'),
              actions: [
                TextButton(
                  onPressed: () {
                    timer?.cancel();
                    Navigator.of(context).pop();
                  },
                  child: const Text('Отмена'),
                ),
              ],
            );
          },
        );
      },
    );
  }
}

void main() => runApp(const MaterialApp(home: CountdownDialogExample()));
→ Ссылка