skip to Main Content

So I’m trying to have a page that you click on the floating action button and a popup dialog/ alert dialog appears with an text field which you enter the name and it creates an item in the list view, also I want that item to be clickable and goes to another page with that name as the new app bar name.

This is my code, but it doesn’t create anything:

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

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

  @override
  State<lists> createState() => _listsState();
}

class _listsState extends State<lists> {
  @override
  Widget build(BuildContext context) {
    String _newItemName = '';
    final List<String> _items = [];
    final textController = TextEditingController();
    int _currentIndex = 0;

    return Scaffold(
      body: _items.length > 0
          ? ListView.builder(
              itemCount: _items.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text('${_items[index]}'),
                );
              },
            )
          : const Center(
              child: Text("You currently have no classes. Add from below."),
            ),
      floatingActionButton: SpeedDial(
        animatedIcon: AnimatedIcons.menu_arrow,
        spacing: 6,
        spaceBetweenChildren: 6,
        backgroundColor: const Color.fromARGB(255, 22, 37, 50),
        foregroundColor: const Color.fromARGB(255, 255, 255, 255),
        children: [
          SpeedDialChild(
              child: const Icon(Icons.group_add), label: "add student"),
          SpeedDialChild(
            child: const Icon(Icons.school),
            label: "add class",
            onTap: () {
              showDialog(
                context: context,
                builder: (context) {
                  return AlertDialog(
                    title: const Text('Add a new class'),
                    content: TextField(
                      controller: textController,
                      autofocus: true,
                      decoration: const InputDecoration(
                          hintText: "Enter the name of the class."),
                    ),
                    actions: [
                      TextButton(
                        child: Text('Cancel'),
                        onPressed: () {
                          Navigator.pop(context);
                        },
                      ),
                      TextButton(
                        child: Text('Add'),
                        onPressed: () {
                          Navigator.pop(context, textController.text);
                        },
                      ),
                    ],
                  );
                },
              );
            },
          )
        ],
      ),
    );
  }
}

2

Answers


  1. In the Add action update the value of _list to contain the item using setState

    return AlertDialog(
             title: const Text('Add a new class'),
             content: TextField(
                        controller: textController,
                        autofocus: true,
                        decoration: const InputDecoration(
                              hintText: "Enter the name of the class."),
                        ),
                        actions: [
                          TextButton(
                            child: Text('Cancel'),
                            onPressed: () {
                              Navigator.pop(context);
                            },
                          ),
                          TextButton(
                            child: Text('Add'),
                            onPressed: () {
                              setState((){
                                 _items.add(textController.text)  // 👈 add list item to the list
                               });
                              Navigator.pop(context, textController.text);
                            },
                          ),
                        ],
                      );
    
    Login or Signup to reply.
    • if you want to wait for showDialog to return the result, you need to use async await.
    • _items variable cannot be final, because final is immutable.
    • if you want to use setState, you must define the variable outside the build method. The _items inside the build method and initialize it to empty So _items will be Reinitialize When redrawing the UI.
    • textEditController should not be defined inside the build method, and its lifecycle should be managed.
    import 'package:flutter/material.dart';
    import 'package:flutter_speed_dial/flutter_speed_dial.dart';
    
    class lists extends StatefulWidget {
      const lists({super.key});
    
      @override
      State<lists> createState() => _listsState();
    }
    
    class _listsState extends State<lists> {
      List<String> _items = [];
      late TextEditingController _textController;
      int _currentIndex = 0;
      @override
      void initState() {
        super.initState();
        _textController = TextEditingController();
      }
    
      @override
      void dispose() {
        _textController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: _items.length > 0
              ? ListView.builder(
                  itemCount: _items.length,
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: Text('${_items[index]}'),
                    );
                  },
                )
              : const Center(
                  child: Text("You currently have no classes. Add from below."),
                ),
          floatingActionButton: SpeedDial(
            animatedIcon: AnimatedIcons.menu_arrow,
            spacing: 6,
            spaceBetweenChildren: 6,
            backgroundColor: const Color.fromARGB(255, 22, 37, 50),
            foregroundColor: const Color.fromARGB(255, 255, 255, 255),
            children: [
              SpeedDialChild(
                  child: const Icon(Icons.group_add), label: "add student"),
              SpeedDialChild(
                child: const Icon(Icons.school),
                label: "add class",
                onTap: () async {
                  final result = await showDialog(
                    context: context,
                    builder: (context) {
                      return AlertDialog(
                        title: const Text('Add a new class'),
                        content: TextField(
                          controller: _textController,
                          autofocus: true,
                          decoration: const InputDecoration(
                              hintText: "Enter the name of the class."),
                        ),
                        actions: [
                          TextButton(
                            child: Text('Cancel'),
                            onPressed: () {
                              Navigator.pop(context);
                            },
                          ),
                          TextButton(
                            child: Text('Add'),
                            onPressed: () {
                              Navigator.pop(context, _textController.text);
                            },
                          ),
                        ],
                      );
                    },
                  );
                  if (result != null) {
                    result as String;
                    setState(() {
                      _items.add(result);
                    });
                  }
                },
              )
            ],
          ),
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search