Jovanovski
Jovanovski

Reputation: 232

Flutter: How to minimize width of DropdownButton

The DropdownButton in Flutter sets its width based on the largest DropdownMenuItem from the items it has. That leaves a lot of white space between the item and the arrow if a small item is selected. How do I make the button scale to just fit the selected item's width?

I tried using Expanded, some Flexible stuff and I still can't make it change its width.

DropdownButton(
    value: null,
    hint: Text("Small text"),
    items: ..., //Text widgets that have more text and are larger than the hint
)

I am trying to get rid of that space underlined between the hint and the arrow: enter image description here

Upvotes: 17

Views: 10075

Answers (6)

Nengha
Nengha

Reputation: 44

I managed to remove the whitespace by defining alignment: Alignment.centerRight. By default, alignment is set to Alignment.centerStart which forces the Text to align start while the Icon is set to align end. So by aligning the text center right it fills the whitespace that appears between the text and icon. Full Code Sample:

DropdownButton(
    alignment: Alignment.centerRight,
    child: .....
     )

Upvotes: 0

Umar Farooqq
Umar Farooqq

Reputation: 1

to remove under line warp Dropdown with DropdownButtonHideUnderline

Upvotes: -2

Marco
Marco

Reputation: 184

The width is actually determined by the widest item provided by the selectedItemBuilder argument (which uses the items if not defined). With this little trick I managed to have it working:

    DropdownButton<T>(
      value: value,
      selectedItemBuilder: (ctx) => [for (final item in items) value], 
      items: items,
      onChanged: (value) => ... update value

The selectedItemBuilder in the example produces a list of repeated items (the one corresponding to the selected value). You will need a stateful widget to handle the value.

Upvotes: 2

willypede
willypede

Reputation: 199

Wrap Dropdown button with ButtonTheme and add alignedDropdown = true like:

ButtonTheme(
  alignedDropdown: true,
  child: DropdownButton(...),
)

alignedDropdown will match the menu items' width with buttons. Then we need specific width, so wrap ButtonTheme with SizedBox or Container:

SizedBox(
  width: 25, // Your width for dropdowns
  child: ButtonTheme(...),
)

Upvotes: 2

Nadav Porat
Nadav Porat

Reputation: 58

If I understand your problem correctly then I have also encountered it and I have a solution. Simply make a Wrap widget as the parent of your DropdownButton. It will make the dropdown menu wrap to the size of the value (not sure how it would react with the null value though)

Wrap(children: <Widget>[DropdownButton(
value: null,
hint: Text("Small text"),
items: //Text widgets that have more text and are larger than the hint
)])

Upvotes: -1

Lucas Matos
Lucas Matos

Reputation: 576

this works:

new Container(
            padding: const EdgeInsets.fromLTRB(10.0, 5, 10, 0),
            child: new Container(
              padding: const EdgeInsets.fromLTRB(10, 5, 5, 5),
              decoration: new BoxDecoration(
                  color: Colors.white,
                  borderRadius: new BorderRadius.only(
                      topLeft: const Radius.circular(5.0),
                      bottomLeft: const Radius.circular(5.0),
                      bottomRight: const Radius.circular(5.0),
                      topRight: const Radius.circular(5.0))),
              child: new Center(
                  child: new Column(children: [
                new DropdownButton(
                  underline: Text(''),
                  icon: Icon(Icons.keyboard_arrow_down),
                  hint: new Text('Small text'),
                  style: TextStyle(
                    color: Colors.white30,
                  ),
                  isExpanded: true,
                  value: _selectedLocation,
                  onChanged: (String newValue) {
                    setState(() {
                      _selectedLocation = newValue;
                    });
                  },
                  items: _locations.map((String location) {
                    return new DropdownMenuItem<String>(
                      value: location,
                      child: new Text(
                        location,
                        style: TextStyle(
                            color: myColour, fontWeight: FontWeight.bold),
                      ),
                    );
                  }).toList(),
                ),
              ])),
            ))

Upvotes: 0

Related Questions