Korenz
Korenz

Reputation: 166

How to change the DropdownButton's icon color? Flutter

In Flutter, I am trying to change the color of the DropdownButton's icon (the down arrow icon) to white color.

I tried using the style property with no help. The text color became white but the icon is still the default grey.

DropdownButton(
         style: TextStyle(color: Colors.white, decorationColor: 
             Colors.white),
         items: this.items,
         value: null,
         hint: Text(SaveOptions[_saveOption], style: TextStyle(color: 
             Colors.white)),
         onChanged: (selectedOption) {
           setState(() {
             _saveOption = selectedOption;
           });
         })

How do I change the color of the arrow icon to white?

Upvotes: 7

Views: 24094

Answers (7)

Alan Negrete
Alan Negrete

Reputation: 420

Wrap your widget around a new Theme that has the values you want set, given that you can go to the source code and see which colors it's using off the theme.

Upvotes: 0

AlvaroSantisteban
AlvaroSantisteban

Reputation: 5336

You can use the fields iconEnabledColor and iconDisabledColor in the following manner:

final myDropDownMenu = DropdownButton<String>(
      iconEnabledColor: Colors.white,
      iconDisabledColor: Colors.white,
      value: myInitialValue,
      // The rest of your code
);

Upvotes: 16

Midhilaj
Midhilaj

Reputation: 4987

Go to DropdownButton class Edit this code

if (!DropdownButtonHideUnderline.at(context)) {
      final double bottom = widget.isDense ? 0.0 : 8.0;
      result = Stack(
        children: <Widget>[
          result,
          Positioned(
            left: 0.0,
            right: 0.0,
            bottom: bottom,
            child: Container(
              height: 1.0,
              decoration: const BoxDecoration(
                border: Border(bottom: BorderSide(color: Color(0xFFBDBDBD), width: 0.0))
              ),
            ),
          ),
        ],
      );
    }

to this

if (!DropdownButtonHideUnderline.at(context)) {
      final double bottom = widget.isDense ? 0.0 : 8.0;
      result = Stack(
        children: <Widget>[
          result,
          Positioned(
            left: 0.0,
            right: 0.0,
            bottom: bottom,
            child: Container(
              height: 1.0,
              decoration: const BoxDecoration(
                border: Border(bottom: BorderSide(color: Colors.red

("Here any color you want")

, width: 0.0))
                  ),
                ),
              ),
            ],
          );
        }

Upvotes: 0

This is a bit of a hack but it gives you complete control over how the drop down looks collapsed, in short make value: null, hint: null, iconsize: null, make a stack that has 2 containers with same sizing: 1 that displays your collapsed dropdown and 1 that detects gestures 'expand'.

class MyDropdownFilled extends StatefulWidget {
  final List<String> dropDownValues;

  const MyDropdownFilled({Key key, @required this.dropDownValues})
      : super(key: key);

  List<DropdownMenuItem<String>> getDropDownMenuItems() {
    return dropDownValues
        .map((itemString) =>
            DropdownMenuItem(child: Text(itemString), value: itemString))
        .toList();
  }

  @override
  _MyDropdownFilledState createState() => _MyDropdownFilledState();
}

class _MyDropdownFilledState extends State<MyDropdownFilled> {
  String _activeDropdown;

  @override
  initState() {
    super.initState();
    _activeDropdown = widget.dropDownValues[0];
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Container(
          width: double.infinity,
          padding: EdgeInsets.all(10.0),
          decoration: BoxDecoration(
              color: primaryColor.shade600,
              borderRadius: BorderRadius.all(Radius.circular(2))),
          child:
              Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
            Text(_activeDropdown, style: Theme.of(context).textTheme.caption),
            Icon(Icons.arrow_drop_down, size: 30, color: Colors.white),
          ]),
        ),
        Container(
          width: double.infinity,
          padding: EdgeInsets.all(10.0),
          decoration: BoxDecoration(
              color: Colors.transparent,
              borderRadius: BorderRadius.all(Radius.circular(2))),
          child: DropdownButtonHideUnderline(
              child: DropdownButton<String>(
            value: null,
            isDense: true,
            iconSize: 0,
            hint: null,
            onChanged: (String newValue) {
              setState(() {
                _activeDropdown = newValue;
              });
            },
            items: widget.dropDownValues.map((String value) {
              return DropdownMenuItem(
                value: value,
                child: Text(value),
              );
            }).toList(),
          )),
        )
      ],
    );
  }
}

Upvotes: 3

KevinM
KevinM

Reputation: 1807

It seems Flutter should have a way to do this, but I don't think it's currently possible. What I did to handle this was to set the "value" to null, "iconSize" to 0, and have the "hint" dynamically generated based on what is selected. Doing this lets you have complete control over hint widget.

DropdownButton<int>(
  value: null,
  iconSize: 0,
  hint: Row(
    children: <Widget>[
      Text(_selected,
        style: TextStyle(
          color: Colors.white,
          fontWeight: FontWeight.w700,
        ),
      ),
      Padding(
        padding: EdgeInsets.only(left: 5),
        child: Icon(
          FontAwesomeIcons.caretDown,
          color: Colors.white,
          size: 20,
        ),
      ),
    ],
  ),
  items: dateRanges.map((Map<String, dynamic> value) {
    return DropdownMenuItem<int>(
      value: value['type'],
      child: Text(
        value['name'],
        style: TextStyle(
          color: Colors.grey[800],
          fontWeight: FontWeight.w700,
        ),
      ),
    );
  }).toList(),
  onChanged: (type) => _onDateRangeTypeChanged(type),
)

Hope this helps.

Upvotes: 0

chemamolins
chemamolins

Reputation: 20568

Since the DropdownButton gets the color from the nearest Theme, you have two options.

The first one is by changing the brightness of the application theme.

And the other is by wrapping your dropdown button with a new Theme with dark brightness.

Theme(
   data: Theme.of(context).copyWith(brightness: Brightness.dark),
   child: DropdownButton(
     style: TextStyle(color: Colors.white, decorationColor: Colors.white),
     items: this.items,
     value: null,
     hint: Text(SaveOptions[_saveOption], style: TextStyle(color: Colors.white)),
     onChanged: (selectedOption) {
       setState(() {
         _saveOption = selectedOption;
       });
     },
   ),
 )

Upvotes: 7

Vinicius Braz Pinto
Vinicius Braz Pinto

Reputation: 8289

Currently the arrow color is hardcoded for DropdownButton:

  Color get _downArrowColor {
    // These colors are not defined in the Material Design spec.
    if (_enabled) {
      if (Theme.of(context).brightness == Brightness.light) {
        return Colors.grey.shade700;
      } else {
        return Colors.white70;
      }
    } else {
      if (Theme.of(context).brightness == Brightness.light) {
        return Colors.grey.shade400;
      } else {
        return Colors.white10;
      }
    }
  }

You can create your own widget to customize this property.

Upvotes: 0

Related Questions