Drowdown Button In Flutter
Tags: flutter, dart, dropdown
Published: 2022-10-26 17:40:01

Hey Guys, 

Have you ever been stuck and you dont know exact thing to do anymore, trust me,    there are some bugs that won't just let you kill them (if you like use Bagon😂)...

Well I came across this bug 🐞 , yeah and I checked through Flutter documentation, Stack Overflow and the likes, couldn't get my solution. 

I was able to figure it out after couple of hours and I will like to share my solution. Also I will be sharing some other solutions I came across just in case my solution doesnt fit. You can get all soluton in one stop, yah.

In this article you will be learning how to use DropDownButton and learn various properties of it in flutter and also get the solution to common bugs associated with this widget.

Lets dive in...

**What is a Dropdown Button 💁🏽‍♂️?**
Dropdown Button is a Material Design button for selecting from a list of items.


    DropdownButton<String>(
      value: dropdownValue,
      icon: const Icon(Icons.arrow_downward),
      elevation: 16,
      style: const TextStyle(color: Colors.deepPurple),
      underline: Container(
        height: 2,
        color: Colors.deepPurpleAccent,
      ),
      onChanged: (String? value) {
        // This is called when the user selects an item.
        setState(() {
          dropdownValue = value!;
        });
      },
      items: list.map<DropdownMenuItem<String>>((String value) 
      {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(value),
        );
      }).toList(),


The Dropdown Button has some properties and methods, To use this widget, you need to have a list of items that you will use in your dropdown. For the above example here is the list that was used

_const List<String> list = <String>['One', 'Two', 'Three'];_

and when you run this in your flutter project, you will get something like this: 👇🏼👇🏼👇🏼👇🏼👇🏼👇🏼

![This image shows the result of above codes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q4g9xvpomv8uotaf4gfe.png)

There you go!!!

**Dropdown Button has a major?**
You have to use this widget right, and if not, you get stuck. This is the major issue with using a Drondown Button.

**Error meesage:**
_Drop down Either or 2 more dropdown were detected with the same value???? _
 


_Lets take this example as our point of focus._


      String _value1;
      String _value2;

      final List<String> nameList = <String>[
       "Name1",
        "Name2",
        "Name3",
        "Name4",
        "Name5",
        "Name6",
        "Name7",
        "Name8"
       ];

       @override
      Widget build(BuildContext context) {
        return Scaffold(
         appBar: AppBar(
         elevation: 2.0,
         title: Text('Hello'),
         ),
        body:  ListView(
            children: <Widget>[
              Row(
                children: <Widget>[
                  Text('Name: '),
                  Center(
                    child: DropdownButton(
                      value: _value1,
                      onChanged: (value) {
                        setState(() {
                          _value1 = value;
                        });
                      },
                      items: nameList.map(
                        (item) {
                          return DropdownMenuItem(
                            value: item,
                            child: new Text(item),
                          );
                        },
                      ).toList(),
                    ),
                  ),
                ],
              ),
              Row(
                children: <Widget>[
                  Text('Name: '),
                  Center(
                    child: DropdownButton(
                      value: _value2,
                      onChanged: (value) {
                        setState(() {
                          _value2 = value;
                        });
                      },
                      items: nameList.map(
                        (item) {
                          return DropdownMenuItem(
                            value: item,
                            child: new Text(item),
                          );
                        },
                      ).toList(),
                    ),
                  ),
                ],
              ),
            ],
          ),
        backgroundColor: Colors.grey[200],
       );
      }
     }

**_One:_**
Always make sure the value of the property "value" is not empty.  

             DropdownButton(
              // Initial Value
              _**value: dropdownvalue,**_
               
              // Down Arrow Icon
              icon: const Icon(Icons.keyboard_arrow_down),   
               
              // Array list of items
              items: items.map((String items) {
                return DropdownMenuItem(
                  value: items,
                  child: Text(items),
                );
              }).toList(),
              // After selecting the desired option,it will
              // change button value to selected value
              onChanged: (String? newValue) {
                setState(() {
                  dropdownvalue = newValue!;
                });
              },
            ),

**_Two:_** 
If the value is going to be promised, that is at a later time the property will get its value, then. check if the value is empty first, if it is empty replaced with a default value.

     DropdownButton(
       value: _value1.isNotEmpty ? _value1 : null, // guard it 
         with null if empty
        items: nameList.map((item) {
           return DropdownMenuItem(
              value: item,
              child: new Text(item),
            );
          }).toList(), 
        );

**_Three:_**
If you are getting your list from the database, make sure the function you call in not in your build context, it should be called once. And the reson why that is so is because when call your api that will get the list within your build context, its get called multipble times as you are using setstate to update the selected value. Here is a complete example code  ------ 
 See here. 👇🏼👇🏼👇🏼👇🏼👇🏼👇🏼👇🏼


      class _ParentBankState extends 
      State<ParentCategory> {
      final _formKey = GlobalKey<FormState>();

       String? _selectedBankCategory;
        // List category = [];
       final List<String> _parentCategory = [
        "Select Category",
       ];
 
       _//Make sure you do your calls here_

      @override
      void initState() {
        //do your calls to get the list from your database 
       //here so that it will be called once...

      final category = context.read<AddMoneyCubit>. 
      ().loadBankList();
       super.initState();
      }

    @override
     Widget build(BuildContext context) {

     //Do not call your api here, why?
     //because buildcontext get build multiple times and that 
     //will make your dropdwon throw that error, because it is 
     //seeing the value beeing used repeatedly...

      var businessBankDropDown =
        BlocBuilder<AddMoneyCubit, AddMoneyState>(
      builder: (context, state) {
        return Form(
          key: _formKey,
          child: ButtonTheme(
            alignedDropdown: true,
            child: DropdownButtonHideUnderline(
              child: DropdownButton<String>(
                menuMaxHeight: 300,
                isExpanded: true,
                value: _selectedParentCategory,
                hint: const Text(
                  "Parent Category",
                  style: TextStyle(fontSize: 14),
                ),
                items: state is LoadBankList
                    ? state.categoryListModel.map((e) {
                        return DropdownMenuItem<String>(
                            value: e.text,
                            child: Row(
                              children: [
                                Text(
                                  e.text,
                                  style: const TextStyle(
                                      fontSize: 14.0, color: 
                  IposColors.black),
                                ),
                              ],
                            ));
                      }).toList()
                    : _parentBank.map((String value) {
                        return DropdownMenuItem<String>(
                            value: value,
                            child: Row(
                              children: [
                                Text(
                                  value,
                                  style: const TextStyle(
                                      fontSize: 14.0, color: 
                        IposColors.black),
                                ),
                              ],
                            ));
                      }).toList(),

                onChanged: (value) {
                  setState(() {
                    print(value);
               _selectedBankCategory = value;
                  });
                },
                style: const TextStyle(fontSize: 30),
               ),
               ),
              ),
             );
             },
            );

        return Container(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height / 16.4,
           decoration: BoxDecoration(
           color: Colors.white,
           borderRadius: BorderRadius.circular(10),
           border: Border.all(
            color: Colors.grey,
           ),
         ),
         child: businessBankDropDown);
        }
      }


This was my Solution.

Thank you for taking your time to go through this.

I hope you have learned to use this awesome widget and this helps you resolve your bugs 🐞🪲  issues...
 
If you would like to discuss this or any related issueChat Me. Follow me on [Twitter](https://twitter.com/Har4lionkest) for More...