androidflutterdartdebuggingmobile

showDialog function in flutter not doing anything


I'm making a simple 'To Do List' app In Flutter, When I press the 'floatingActionButton' it's supposed to to show a pop-up where the user can input a new task, But nothing is displayed when the button is pressed, Testing on an actual Android phone, Here's the code:

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

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


class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  List<String> tasks = [];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(

        appBar: AppBar(
          backgroundColor: Colors.yellow[700],
          title: Text("To Do List"),
          centerTitle: true,
        ),

        body: Container(margin: EdgeInsets.all(20), child:
          Column(children:
              tasks.map(
                  (name) => Task(name: name, delete: () => setState(()=>tasks.remove(name)))
              ).toList() as List<Widget>
          )
        ),

        floatingActionButton: IconButton(icon: Icon(Icons.add), onPressed: displayPrompt),

      )
    );
  }

  Future<void> displayPrompt() async {
    await showDialog(
        context: context,
        builder: (BuildContext context) => TextField(
          onSubmitted: (String input) => setState(()=>tasks.add(input)),
          decoration: InputDecoration(hint: Text("Please enter a task")),
          autocorrect: true,
          autofocus: true,
        )
    );
  }

}

Here's the custom Widget I made:

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

class Task extends StatelessWidget {

  final String name;
  final VoidCallback delete;

  const Task({required this.name, required this.delete, super.key});

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Row(children: [
        Text(name),
        IconButton(icon: Icon(Icons.delete), onPressed: delete,)
      ]),
    );
  }

Solution

  • Try to separate the MaterialApp context and put in parent and return a Material widget like AlertDialog from showDialog's builder.

    You can find more https://api.flutter.dev/flutter/material/AlertDialog-class.html

    void main() => runApp(MaterialApp(home: MyApp()));
    
    class MyApp extends StatefulWidget {
      const MyApp({super.key});
    
      @override
      State<MyApp> createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      List<String> tasks = [];
    
      Future<void> displayPrompt() async {
        await showDialog(
          context: context,
          builder: (BuildContext context) => AlertDialog(
            content: TextField(
              onSubmitted: (String input) => setState(() => tasks.add(input)), 
              decoration: InputDecoration(hint: Text("Please enter a task")),
              autocorrect: true,
              autofocus: true,
            ),
          ),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            backgroundColor: Colors.yellow[700],
            title: Text("To Do List"),
            centerTitle: true,
          ),
          body: Container(
              margin: EdgeInsets.all(20),
              child: Column(
                  children: tasks
                      .map((name) => Task(
                          name: name,
                          delete: () => setState(() => tasks.remove(name))))
                      .toList() as List<Widget>)),
          floatingActionButton: IconButton(
            icon: Icon(Icons.add),
            onPressed: displayPrompt,
          ),
        );
      }
    }