skip to Main Content

I have this code where I have a dropdown where a user can select some options, the problem is after selecting it the new value does not appear. I tried using setState for something else and it works outside the page of the dialog but nothing rebuilds inside the dialog.

import 'package:flutter/material.dart';

import '../../../variables.dart';

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

  @override
  State<HomePageTeacher> createState() => _HomePageTeacherState();
}

class _HomePageTeacherState extends State<HomePageTeacher> {
  String name = "//name of user//"; // Replace with name of user
  String? selectedVal;
  static const menuItems = [
    "Info",
    "Urgent",
  ];
  final List<DropdownMenuItem<String>> _popUpItems = menuItems
      .map((String value) => DropdownMenuItem<String>(
            value: value,
            child: Text(value),
          ))
      .toList();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        tooltip: "Add Update",
        onPressed: () {
          showDialog(
            context: context,
            builder: (context){
              return AlertDialog(
                title: const Text('Input Text'),
                content: const TextField(
                  maxLength: 200,
                  maxLines: null,
                  decoration: InputDecoration(hintText: 'Enter text'),
                ),
                actions: [
                  TextButton(
                    child: const Text('Cancel'),
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                  ),
                  DropdownButton(
                    value: selectedVal,
                    hint: const Text("Type of Message"),
                    items: _popUpItems,
                    onChanged: (newValue) {
                      if (newValue != null) {
                        setState(() {
                          selectedVal = newValue;
                          debugPrint(selectedVal);
                        });
                      }
                    },
                  )
                ],
              );
            },
          );
        },
        child: const Icon(Icons.add),

Set State works outside the dialog but for some reason doesn’t inside the dialog.

2

Answers


  1. Wrap the Dropdown buttom with a StatefullBuilder
    Like :

     StatefullBuilder(builder:(context,state){
    return DropdownButton(
                        value: selectedVal,
                        hint: const Text("Type of Message"),
                        items: _popUpItems,
                        onChanged: (newValue) {
                          if (newValue != null) {
                            state(() {
                              selectedVal = newValue;
                              debugPrint(selectedVal);
                            });
                          }
                        },
                      )
    })
    
    Login or Signup to reply.
  2. I do not think the state will rebuild inside the showDialog widget, because when you do showDialog it makes a new route and push it onto the navigation stack it remains on the screen until you close/pop it. This is actually in a separate route. so when you do the setState will not affect anything to the parent widget that calls the showDialog.

    So I suggest you to make a separate widget to handle the state changes and show it from the showDialog.

    class _HomePageTeacherState extends State<HomePageTeacher> {
      String name = "//name of user//"; // Replace with name of user
      String? selectedVal;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          floatingActionButton: FloatingActionButton(
            tooltip: "Add Update",
            onPressed: () {
              showDialog(
                context: context,
                builder: (context) {
                  return UpdateDialog(
                    onChanged: (newValue) {
                      setState(() {
                        selectedVal = newValue;
                        debugPrint(selectedVal);
                      });
                    },
                  );
                },
              );
            },
            child: const Icon(Icons.add),
          ),
        );
      }
    }
    
    class UpdateDialog extends StatefulWidget {
      final ValueChanged<String?> onChanged;
    
      const UpdateDialog({required this.onChanged, Key? key}) : super(key: key);
    
      @override
      _UpdateDialogState createState() => _UpdateDialogState();
    }
    
    class _UpdateDialogState extends State<UpdateDialog> {
      static const menuItems = ["Info", "Urgent"];
      String? selectedValue;
    
      @override
      Widget build(BuildContext context) {
        return AlertDialog(
          title: const Text('Input Text'),
          content: TextField(
            maxLength: 200,
            maxLines: null,
            decoration: InputDecoration(hintText: 'Enter text'),
          ),
          actions: [
            TextButton(
              child: const Text('Cancel'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
            DropdownButton<String>(
              value: selectedValue,
              hint: const Text("Type of Message"),
              items: menuItems.map((String value) {
                return DropdownMenuItem<String>(
                  value: value,
                  child: Text(value),
                );
              }).toList(),
              onChanged: (newValue) {
                setState(() {
                  selectedValue = newValue!;
                  widget.onChanged(newValue!);
                });
              },
            ),
          ],
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search