Как закрыть указанный c Flutter AlertDialog? - PullRequest
0 голосов
/ 05 августа 2020

Шаги для воспроизведения:

  1. Скопируйте и вставьте приведенный ниже код в DartPad.dev/flutter

  2. Выполните запуск

  3. Нажмите кнопку Do Api Call

  4. вы должны увидеть два всплывающих окна, одно внизу и одно вверху

  5. Через 5 секунд , нижний желательно закрывать, а не верхний, вместо этого закрывается верхний

Как закрыть нижний и оставить открытым верхний?

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: CloseSpecificDialog(),
        ),
      ),
    );
  }
}

class CloseSpecificDialog extends StatefulWidget {
  @override
  _CloseSpecificDialogState createState() => _CloseSpecificDialogState();
}

class _CloseSpecificDialogState extends State<CloseSpecificDialog> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: RaisedButton(
        child: Text('Do API call'),
        onPressed: () async {
          showDialogBelow();
          showDialogAbove();
          await Future.delayed(Duration(seconds: 5));
          closeDialogBelowNotAbove();
        },
      )),
    );
  }

  void showDialogBelow() {
    showDialog(
        context: context,
        builder: (BuildContext contextPopup) {
          return AlertDialog(
            content: Container(
              width: 350.0,
              height: 150.0,
              child: Center(
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    CircularProgressIndicator(),
                    Text('I am below (you should not see this after 5 sec)'),
                  ],
                ),
              ),
            ),
          );
        });
  }

  void showDialogAbove() {
    showDialog(
        context: context,
        builder: (BuildContext contextPopup) {
          return AlertDialog(
            content: Container(
              height: 100.0,
              child: Center(
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    CircularProgressIndicator(),
                    Text('I am above (this should not close)'),
                  ],
                ),
              ),
            ),
          );
        });
  }

  /// This should close the dialog below not the one above
  void closeDialogBelowNotAbove() {
    Navigator.of(context).pop();
  }
}

Ответы [ 2 ]

0 голосов
/ 05 августа 2020

Popping удалит маршрут, который был добавлен последним, а showDialog просто подталкивает новый маршрут с помощью dialogue, вы можете напрямую использовать Dialog виджеты в стеке и управлять состоянием с помощью логической переменной, чтобы достичь того же эффект,

class _MyHomePageState extends State<MyHomePage> {
  bool showBelow = true;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
      await Future.delayed(Duration(seconds: 5));
      setState(() {
        showBelow = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: <Widget>[
          if(showBelow) AlertDialog(
            title: Text('Below..'),
            content: Text('Beyond'),
          ),
          AlertDialog(
            title: Text('Above..'),
          ),
        ],
      ),
    );
  }
}
0 голосов
/ 05 августа 2020

Удалить

 await Future.delayed(Duration(seconds: 5));
 closeDialogBelowNotAbove();

Добавить Future.delayed

void showDialogAbove() {
    showDialog(
        context: context,
        builder: (BuildContext contextPopup) {
          Future.delayed(Duration(seconds: 5), () {
            closeDialogBelowNotAbove();
          });
          return AlertDialog(
            content: Container(
              height: 100.0,
              child: Center(
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    CircularProgressIndicator(),
                    Text('I am above (this should not close)'),
                  ],
                ),
              ),
            ),
          );
        });
  }

Примечание: Метод Navigator.pop () всегда появляется над предупреждением / виджетом, доступным на экране , поскольку он работает с BuildContext, который в данный момент имеет виджет.

...