flutterdartflutter-layoutflutter-dropdownbuttonflutter-dialog

how to design dialog box inside DropdownButtonFormField in flutter?


I have DropdownButtonFormField when I click on it a DialogBox with a list of items should appear, so I can select one item and it should return the selected item in DropdownButtonFormField.I tried with DropdownMenuItem but I need with DialogBox so that it looks good. So basically I wanted to replace the DropdownMenuItem with DialogBox. and I don't know how to do that I'm new to flutter, please help me with this. below I will attach images that I want to get.reference images

 import 'package:flutter/material.dart';
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Dialog Box and return value',
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
    
      @override
      State<StatefulWidget> createState() {
        return MyHomePageState();
      }
    }
    
    class MyHomePageState extends State<MyHomePage> {
      String  selectedLanguage =" ";
      var javascript ="java";
      var c = "C";
      var cpp = "C++";
      var python = "Python";
    
      @override
      Widget build(BuildContext context) {
        return Scaffold (
            appBar: AppBar(
                title: Text("Flutter SimpleDialog Example")
            ),
            body: Container(
              color: Colors.grey,
              child: Center (
                  child: Column (
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        Container(
                          color: Colors.white,
                          height: 50,
                          width: 150,
                          child: DropdownButtonFormField(
                            items: [],
                            hint: Text("Select"),
                          ),
                        ),
                      ]
                  )
              ),
            )
        );
      }
    
      showMyAlertDialog(BuildContext context) {
    
        // Create SimpleDialog
        SimpleDialog dialog = SimpleDialog(
          title: const Text('Select a Language:'),
          children: <Widget>[
            SimpleDialogOption(
                onPressed: () {
                  // Close and return value
                  Navigator.pop(context, javascript);
                },
                child: Text(javascript)
            ),
            SimpleDialogOption(
              onPressed: () {
                // Close and return value
                Navigator.pop(context, c);
              },
              child:  Text(c),
            ),
            SimpleDialogOption(
              onPressed: () {
                // Close and return value
                Navigator.pop(context, cpp);
              },
              child:  Text(cpp),
            ),
            SimpleDialogOption(
              onPressed: () {
                // Close and return value
                Navigator.pop(context, python);
              },
              child:  Text(python),
            )
          ],
        );
    
        // Call showDialog function to show dialog.
        Future futureValue = showDialog(
            context: context,
            builder: (BuildContext context) {
              return dialog;
            }
        );
    
        futureValue.then( (language) => {
          this.setState(() {
            this.selectedLanguage = language;
          })
        });
      }
    
    }

Solution

  • I've included some comment that can help you to understand the concept I've applied.

    void main() => runApp(
          const MaterialApp(
            home: MyApp(),
          ),
        );
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Dialog Box and return value',
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: const MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({Key? key}) : super(key: key);
    
      @override
      State<StatefulWidget> createState() {
        return MyHomePageState();
      }
    }
    
    class MyHomePageState extends State<MyHomePage> {
      String? selectedLanguage;
    
      List<String> languages = ["java", "C", "C++", "Python"];
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text("Flutter SimpleDialog Example")),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Container(
                  color: Colors.white,
                  height: 50,
                  width: 150,
                  child: InkWell(
                      onTap: () async {
                        showMyAlertDialog(context);
                      },
                      child: Container(
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Text("${selectedLanguage ?? 'Select'}   "),
                            const Icon(
                              Icons.arrow_drop_down,
                            ),
                          ],
                        ),
                      )
                      //  DropdownButtonFormField(
                      //   items: [],
                      //   hint: Text("Select"),
                      // ),
                      ),
                ),
              ],
            ),
          ),
        );
      }
    
      showMyAlertDialog(BuildContext context) {
        showDialog(
          context: context,
          builder: (context) {
            return AlertDialog(
              content: StatefulBuilder(
                //* dialog is on different widget Tree. check dev-tools
                builder: (context, setStateD) {
                  return Row(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      const Text("Language"),
                      const SizedBox(width: 12),
                      Column(
                        mainAxisSize: MainAxisSize.min,
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          ...List.generate(
                            languages.length,
                            (index) => item(
                              text: languages[index], //sent String
                              isSelected: languages[index] ==
                                  selectedLanguage, //check it is selected or not
                              ontap: () {
                                /// for inner dialog changes
                                setStateD(() {
                                  selectedLanguage = languages[index];
                                });
                                Navigator.of(context)
                                    .pop(); // if you wish to close the dilog on Select
    
                                setState(() {
                                  //* for class state changes
                                  selectedLanguage = languages[index];
                                });
                                print(selectedLanguage);
                              },
                            ),
                          )
                        ],
                      )
                    ],
                  );
                },
              ),
            );
          },
        );
      }
    
      Widget item(
          {required String text,
          required bool isSelected,
          required Function ontap}) {
        return Padding(
          padding: const EdgeInsets.only(
            bottom: 4,
          ),
          child: InkWell(
            onTap: () => ontap(),
            child: Row(
              children: [
                Text(text),
                const SizedBox(
                  width: 10,
                ),
                if (isSelected)
                  const Icon(Icons
                      .check), // show only check while it is selected, or you can use the same logic on Main row item
              ],
            ),
          ),
        );
      }
    }