47

In Flutter, I can build a Dropdown with DropdownMenuItems, like this: enter image description here

The DropdownMenuItems I add are always wider than the dropdown itself:

enter image description here

How do you adjust the width of the DropdownMenuItem, or remove the extra horizontal padding?

My DropdownMenuItem widget looks like this:

DropdownMenuItem(
    value: unit.name,
    child: Text('hey'),
);

while my Dropdown widget looks like this:

return Container(
    width: 300.0,
    child: DropdownButtonHideUnderline(
      child: DropdownButton(
        value: name,
        items: listOfDropdownMenuItems,
        onChanged: onChanged,
        style: Theme.of(context).textTheme.title,
      ),
    ),
);
Mary
  • 18,347
  • 23
  • 59
  • 76

6 Answers6

101

This feature has been added. See https://github.com/flutter/flutter/pull/14849

You can now wrap it in a ButtonTheme and set alignedDropdown to true.

return Container(
    width: 300.0,
    child: DropdownButtonHideUnderline(
      child: ButtonTheme(
        alignedDropdown: true,
          child: DropdownButton(
            value: name,
            items: listOfDropdownMenuItems,
            onChanged: onChanged,
            style: Theme.of(context).textTheme.title,
         ),
      ),
    ),
);
Mary
  • 18,347
  • 23
  • 59
  • 76
  • 9
    Is it possible to set height of DropDown Button. – Shangari C Jul 10 '19 at 10:38
  • @ShangariC yes, I think you can use `padding`. – Tony Sep 07 '20 at 08:07
  • 1
    now the opened dropdown menu matches the button, in total size, but the text itself don't align, it seem to be the padding in each item that causing problem. how do I remove the padding on individual choices? if I add it to the item directly it also add padding to selected (button item) – shababhsiddique Oct 26 '21 at 07:57
  • 4
    this proposed solution creates a new problem where the dropdown label text is no longer aligned as it is now indented – mister_cool_beans Apr 29 '22 at 15:02
35

I solved this problem with changing isExpanded to true;

return Container(
    width: 300.0,
    child: DropdownButtonHideUnderline(
      child: DropdownButton(
        isExpanded: true,
        value: name,
        items: listOfDropdownMenuItems,
        onChanged: onChanged,
        style: Theme.of(context).textTheme.title,
      ),
    ),
);
Mehmet Ali Bayram
  • 7,222
  • 2
  • 22
  • 27
  • Didn't help me. – atereshkov Jan 07 '20 at 11:07
  • What about padding? – Yudhishthir Singh Jan 23 '20 at 08:46
  • showing error in console - Unfortunately, this object's geometry is not known at this time, probably because it has never been laid out. This means it cannot be accurately hit-tested. E/flutter (22476): If you are trying to perform a hit test during the layout phase itself, make sure you only hit test nodes that have completed layout (e.g. the node's children, after their layout() method has been called). – Kamlesh Feb 05 '21 at 08:18
10

isExpanded: true will stretch the width to full screen. But if you want a customise drop-down. Here is my customdropdown.dart

import 'package:flutter/material.dart';
class CustomDropDown extends StatelessWidget {
  final value;
  final List<String> itemsList;
  final Color dropdownColor;
  final Function(dynamic value) onChanged;
  const CustomDropDown({
    @required this.value,
    @required this.itemsList,
    this.dropdownColor,
    @required this.onChanged,
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(left: 20, top: 3, bottom: 3, right: 20),
      child: Container(
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(10),
          color: Colors.white,
        ),
        child: DropdownButtonHideUnderline(
          child: Padding(
            padding: const EdgeInsets.only(left: 14.0, right: 14),
            child: DropdownButton(
              isExpanded: true,
              dropdownColor: dropdownColor,
              value: value,
              items: itemsList
                  .map((String item) => DropdownMenuItem<String>(
                        value: item,
                        child: Text(item),
                      ))
                  .toList(),
              onChanged: (value) => onChanged(value),
            ),
          ),
        ),
      ),
    );
  }
}

Now you can call it like this.

CustomDropDown(
   value: selectedValue,
   itemsList: ['Music', 'Photographer'],
   onChanged: (value) {
        setState(() {
            selectedValue = value;
        });
    },
),
Abdullah Khan
  • 1,365
  • 15
  • 15
2

I solved it by adding isExpanded: true then wraping dropdown to a container then again wraping to padding widget this worked for me

code : -

Container(
                        height: 60,
                        width: double.infinity,
                         decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(10),
                    border: Border.all(color: borderContainerColor, width: 3)),
                        child: Padding(
                          padding: const EdgeInsets.all(8.0), //here include this to get padding
                          child: DropdownButton(

                            isExpanded: true,
                            underline: Container(),

                            alignment: Alignment.bottomCenter,


                            elevation: 0,
                            borderRadius: BorderRadius.circular(5 ),
                            value: dropdownvalue,
                            icon: const Icon(Icons.keyboard_arrow_down),

                            items: items.map((String items) {
                              return DropdownMenuItem(
                                value: items,
                                child: Text(items),
                              );
                            }).toList(),
                            onChanged: (String? newValue) {
                              setState(() {
                                dropdownvalue = newValue!;
                              });
                            },
                          ),
                        ),
                      ),

Output

2

In my case this is working.

                  Container(
                    decoration: BoxDecoration(
                        border: Border.all(
                            color: ContactColors.hint2, width: 2)),
                    width: double.infinity,
                    margin: const EdgeInsets.all(5),
                    child: DropdownButtonHideUnderline(
                        child: DropdownButton<String>(
                      hint: new Text("Select City"),
                      isExpanded: true,
                      alignment: Alignment.center,
                      value: dropdownValue,
                      icon: const Icon(Icons.arrow_downward),
                      elevation: 16,
                      style: const TextStyle(color: ContactColors.white),
                      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: Container(
                            margin: const EdgeInsets.all(10),
                            child: Text(value,
                                style: const TextStyle(
                                    color: ContactColors.primaryColor)),
                          ),
                        );
                      }).toList(),
                    )),
                  ),
Muhaiminur Rahman
  • 3,066
  • 20
  • 27
1

Try with this parameter isDense it will shrink the widget and extra padding will be removed just like this

DropdownButton(
          isDense: true,
          value : lname_listValue,
          items: casteEDList.map((String items)
                   {
                       return DropdownMenuItem(
                              value: items,
                              child: Text(items),);
                   }).toList(),
                   onChanged: (String? newValue) {
                              setState(() {
                              lname_listValue = newValue!;
                              },);
                   },
  ),
Damini Suthar
  • 1,470
  • 2
  • 14
  • 43