Gabriel
Gabriel

Reputation: 43

Flutter showDialog not working on a simple test

I am trying flutter and have problems in making a simple showdialog work. I tried a simple test with one button:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter Test',
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.teal,
          title: Text('Flutter'),
        ),
        body: Center(
          child: ListView(
            padding: EdgeInsets.all(8),
            children: <Widget>[
              Container(
                child: RaisedButton(
                  child: Text('My Button'),
                  onPressed: () => {
                    showDialog(
                      context: context,
                      barrierDismissible: false,
                      builder: (context) {
                        return AlertDialog(
                          title: Text('Test'),
                          content: Text('Dialog content'),
                        );
                      },
                    ),
                  },
                  color: Colors.cyan,
                  textColor: Colors.white,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

I expect the alert to pop on button tap. What am I missing? I also tried it with the showdialog in a separate custom function call, same result.

Upvotes: 3

Views: 15047

Answers (2)

Ben Butterworth
Ben Butterworth

Reputation: 28478

It can be done in a StatelessWidget, like in this DartPad pad.

  • Sidenote: I've had to use a Builder because the context in MyApp's build method doesn't have a MaterialApp ancestor.
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  
  showAppDialog(BuildContext context) {
    print("Showing app dialog");
    showDialog(context: context,
              builder: (context) {
              return AlertDialog(
              title: const Text(
                "This is a dialog that works.",
              ),
              icon: const Icon(Icons.delete),
              actions: [
                TextButton(
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                    child: const Text("OK"),
                ),
              ],
            );

              });
  }
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(body: SafeArea(child: Builder(
        builder: (context) {
          return TextButton(child: Text("Show dialog"), onPressed: () => showAppDialog(context),);
        }
      ))),
    );
  }
}

PS: You're already using showDialog, why does this answer suggest you to do that 🤔.

Upvotes: 1

J. S.
J. S.

Reputation: 9625

You need to use the showDialog method provided by Flutter, as seen on the example here. Check my example below with your button but using the showDialog method:

class DialogIssue extends StatefulWidget {
  @override
  _DialogIssueState createState() => _DialogIssueState();
}

class _DialogIssueState extends State<DialogIssue> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: RaisedButton(
        child: Text('My Button'),
        onPressed: () => _confirmDialog(),
        color: Colors.cyan,
        textColor: Colors.white,
      ),
    );
  }

  Future<void> _confirmDialog() async {
    switch (await showDialog<bool>(
        context: context,
        builder: (BuildContext context) {
          return SimpleDialog(
            title: const Text('True or false'),
            children: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  SimpleDialogOption(
                    onPressed: () { Navigator.pop(context, true); },
                    child: const Text('Confirm',
                      style: TextStyle(fontWeight: FontWeight.bold),
                    ),
                  ),
                  SimpleDialogOption(
                    onPressed: () { Navigator.pop(context, false); },
                    child: const Text('Cancel'),
                  ),
                ],
              ),
            ],
          );
        }
    )){
      case true:
        print('Confirmed');
        break;

      case false:
        print('Canceled');
        break;

      default:
        print('Canceled');
    }
  }
}

Upvotes: 3

Related Questions