HTMHell
HTMHell

Reputation: 6016

How to align DropdownButton next to a TextField in Flutter?

I would like to vertically align a DropdownButton right next to a TextField.

  Row(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: <Widget>[
      DropdownButton<String>(
        ...
      ),
      Flexible(
        child: TextField(
          ...
        ),
      ),
    ],
  )

The current behavior is:

enter image description here

As you can see, the bottom lines aren't aligned. I guess that's happening due to a differences in height. What would be a good practice to fix that? (I'm guessing not using a fixed height)


My final goal is something like this:

enter image description here

Where both lines and the text of DropdownButton and TextField are vertically aligned.

Upvotes: 14

Views: 7442

Answers (7)

Vikas Pachar
Vikas Pachar

Reputation: 37

You can simply decrease contentPadding in InputDecoration of DropdownButtonFormField

Upvotes: -1

Brian Mahecha
Brian Mahecha

Reputation: 217

Hope this helps but I got it working! Key prop that did it for me was setting contentPadding for widgets in row to 0.0

Row(
   children: <Widget>[
       Flexible(
       flex: 2,
       child: TextFormField(
          keyboardType: TextInputType.number,
          inputFormatters: <TextInputFormatter>[
          WhitelistingTextInputFormatter.digitsOnly
          ],
          decoration: InputDecoration(
             labelText: 'Width',
             contentPadding: EdgeInsets.all(0.0),
          ),
          onChanged: (String newValue) {
             _stashItem.width = "$newValue $_widthUnit";
          },
          )),
          Flexible(
          flex: 1,
          child: DropdownButtonFormField(
          decoration: InputDecoration(
             contentPadding: EdgeInsets.all(0.0)
          ),
          value: _widthUnit,
          items: ['cm', 'm', 'in', 'ft', 'yd']
              .map((String unit) =>
                 DropdownMenuItem<String>(
                   value: unit, child: Text(unit)))
                   .toList(),
          onChanged: (value) => setState(() {
              _widthUnit = value;
          })),
          )
          ],
       ),

Upvotes: 9

ibby
ibby

Reputation: 41

A bit late, but I had the same issue albeit with a slightly different layout:

  1. I used TextFormField rather than TextField.
  2. I used DropdownButtonFormField rather than DropDownButton.
  3. Both fields were wrapped in Flexible widgets within the Row, with mainAxisSize set to MainAxisSize.min.
  4. My text field was laid out to the left of the dropdown.

That being said, setting crossAxisAlignment to CrossAxisAlignment.end worked for me.


Try this:

Row(
  mainAxisSize: MainAxisSize.min,  // see 3
  crossAxisAlignment: CrossAxisAlignment.start,
  children: <Widget>[
    Flexible(  // see 3
      child: DropdownButtonFormField<String>(  // see 2
        ...
      ),
    ),
    Flexible(
      child: TextFormField(  // see 1
        ...
      ),
    ),
  ],
)

Upvotes: 4

HTMHell
HTMHell

Reputation: 6016

I ended up editing the padding of the TextField's content, and used CrossAxisAlignment.center instead of CrossAxisAlignment.start:

  Row(
    crossAxisAlignment: CrossAxisAlignment.center,
    children: <Widget>[
      DropdownButton<String>(
        ...
      ),
      Flexible(
        child: TextField(
          decoration: InputDecoration(
            contentPadding: EdgeInsets.all(6.0),
          ),
        ),
      ),
    ],
  )

Result:

enter image description here

(You see space between them due to a SizedBox added)

Upvotes: 2

Abdou Ouahib
Abdou Ouahib

Reputation: 886

Try this:

Container(
  decoration: BoxDecoration(
    border: Border(
      //TODO: Customize the underline here
      bottom: BorderSide(
        color: Colors.white70,
        width: 0.5,
      ),
    ),
  ),
  child: Row(
    crossAxisAlignment: CrossAxisAlignment.center,
    children: [
      DropdownButton<String>(
        onChanged: (c) {},
        underline: Container(),
        items: [
          DropdownMenuItem<String>(
            child: Text('Email'),
          )
        ],
      ),
      Flexible(
        child: TextField(
          decoration: InputDecoration(
            border: InputBorder.none,
          ),
        ),
      ),
    ],
  ),
),

Upvotes: 1

Marko Devcic
Marko Devcic

Reputation: 1101

Try this:

Row(
    Row(mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end
    children: <Widget>[
      Expanded(
        flex: 1
        child: ButtonTheme(
                   alignedDropdown: true,
                   child: DropdownButton<String>(
        ...
      ))),
       Expanded(
         flex: 6
         child: TextField(
          ...
        ),
      ),
    ],
  )

Upvotes: 1

Matiullah Karimi
Matiullah Karimi

Reputation: 1314

I am not sure whether this solution helps you or not, but I think its better than using row.

 TextField(
    decoration: InputDecoration(
       prefix: DropdownButton(underline: Container(), ...)
    ),
 )

Upvotes: 2

Related Questions