skip to Main Content

In the below code a popUp dialog is shown. I want the _startLongRunningLoop to be called once popup dialog is closed. Right now, the popup dialog remains open until _startLongRunningLoop is complete. How can I do it?

Simplified dummy example

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Dialog Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  void _showFormDialog(BuildContext context) {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Form Dialog'),
          content: FormDialog(),
        );
      },
    );
    _startLongRunningLoop();
  }

  void _startLongRunningLoop() {
    int count = 0;
    while (count < 1000000) {
      print('Long running loop: $count');
      count++;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Dialog Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            _showFormDialog(context);
          },
          child: Text('Open Form Dialog'),
        ),
      ),
    );
  }
}

class FormDialog extends StatefulWidget {
  @override
  _FormDialogState createState() => _FormDialogState();
}

class _FormDialogState extends State<FormDialog> {
  final _formKey = GlobalKey<FormState>();

  void _submitForm() {
    if (_formKey.currentState!.validate()) {
      Navigator.of(context).pop();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          TextFormField(
            decoration: InputDecoration(labelText: 'Name'),
            validator: (value) {
              if (value == null || value.isEmpty) {
                return 'Please enter your name';
              }
              return null;
            },
          ),
          SizedBox(height: 16.0),
          ElevatedButton(
            onPressed: _submitForm,
            child: Text('Submit'),
          ),
        ],
      ),
    );
  }
}

In this example, even though Navigator.pop() is called, the dialog still remains on screen until _startLongRunningLoop is completed.

enter image description here

As you can see, the button is pressed and the popup dismisses once the _startLongRunningLoop is complete

Things I have tried

Sol1

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Dialog Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  void _showFormDialog(BuildContext context) async {
    var t = await showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Form Dialog'),
          content: FormDialog(),
        );
      },
    );
    if (t == "true") {
      _startLongRunningLoop();
    }
  }

  void _startLongRunningLoop() {
    int count = 0;
    while (count < 1000000) {
      print('Long running loop: $count');
      count++;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Dialog Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            _showFormDialog(context);
          },
          child: Text('Open Form Dialog'),
        ),
      ),
    );
  }
}

class FormDialog extends StatefulWidget {
  @override
  _FormDialogState createState() => _FormDialogState();
}

class _FormDialogState extends State<FormDialog> {
  final _formKey = GlobalKey<FormState>();

  void _submitForm() {
    if (_formKey.currentState!.validate()) {
      Navigator.of(context).pop("true");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          TextFormField(
            decoration: InputDecoration(labelText: 'Name'),
            validator: (value) {
              if (value == null || value.isEmpty) {
                return 'Please enter your name';
              }
              return null;
            },
          ),
          SizedBox(height: 16.0),
          ElevatedButton(
            onPressed: _submitForm,
            child: Text('Submit'),
          ),
        ],
      ),
    );
  }
}

2

Answers


  1. Hello you can try something like this :

    var valueReturned = await showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
                title: const Text("Title :"),
                content: CustomForm(
                    lastClosePrice: latestPrice.close,
                    onBuy: (double _entryPrice, int _qty, double _targetPrice) {
                        print("Buy button pressed");
                        await setPuzzleSubmissionDTO(PuzzleSubmissionDTO(
                            entryPrice: _entryPrice,
                            targetPrice: _targetPrice,
                            qty: _qty,
                        ));
                        Navigator.of(context).pop(valueYouWantToReturned);
                    },
                );
            );
        }
    );
    if(valueReturned){
        //Treatment
    }
    
    Login or Signup to reply.
  2. Just await the showDialog and the next function will call once the dialog is closed

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search