Search code examples
flutterflutter-layoutdropdownbutton

How to set different value instead of items's value in DropdownButton in flutter?


I want to achieve different values behind the scene, for example, if the user selects "United State of America" behind the scene I want a value "USA" only. How can I achieve this?

Here is my button:

DropdownButton<String>(
                        isExpanded: true,
                        underline: SizedBox(),
                        icon: SvgPicture.asset("assets/icons/dropdown.svg"),
                        value: dropdownValue,
                        items: [
                          'Nepal',
                          'India',
                          'United States',
                          'Denmark',
                          'UK',
                          'World Wide'
                        ].map<DropdownMenuItem<String>>((String value) {
                          return DropdownMenuItem<String>(
                            value: value,
                            child: Text(value),
                          );
                        }).toList(),
                        onChanged: (newValue) {
                          setState(() {
                            dropdownValue = newValue;
                          });
                        },
                      ),

Solution

  • What you can do is create a CountryOption class with a key('USA' in your example) and a fullName ('United States' in your example).

    You then create a list of dropdown items of CountryOption instead of String, so you can store the currently selected CountryOption and you have both the key and fullName properties available for later use.

    I would also recommend loading your list of items only once, not on each rebuild.

    import 'package:flutter/material.dart';
    
    class CountriesButton extends StatefulWidget {
      const CountriesButton({Key key}) : super(key: key);
    
      @override
      _CountriesButtonState createState() => _CountriesButtonState();
    }
    
    class _CountriesButtonState extends State<CountriesButton> {
      List<DropdownMenuItem<CountryOption>> _countryItems;
      CountryOption _selectedCountry;
    
      @override
      void initState() {
        // Get all countries
        List<CountryOption> countries = CountryOption.allCountries;
    
        // Initialise your items only once
        _countryItems = countries.map<DropdownMenuItem<CountryOption>>(
          (CountryOption countryOption) {
            return DropdownMenuItem<CountryOption>(
              value: countryOption,
              child: Text(countryOption.fullName),
            );
          },
        ).toList();
    
        // Initialiste your dropdown with the first country in the list
        // (might be different in your specific scenario)
        _selectedCountry = countries[0];
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
          child: DropdownButton<CountryOption>(
            isExpanded: true,
            underline: SizedBox(),
            icon: SvgPicture.asset("assets/icons/dropdown.svg"),
            value: _selectedCountry,
            items: _countryItems,
            onChanged: (newValue) {
              setState(() {
                _selectedCountry = newValue;
              });
            },
          ),
        );
      }
    }
    
    class CountryOption {
      final String key;
      final String fullName;
    
      CountryOption(this.key, this.fullName);
    
      static List<CountryOption> get allCountries => [
            CountryOption('nepal', 'Nepal'),
            CountryOption('india', 'India'),
            CountryOption('USA', 'United States'),
            CountryOption('denmark', 'Denmark'),
            CountryOption('uk', 'UK'),
            CountryOption('world', 'World Wide'),
          ];
    }
    

    Let me know if something is not clear or if you have any questions.