How should I customize DropdownButtons and Dropdow

2020-03-01 07:36发布

The default DropdownButton with DropdownMenuItems returns a light-grey dropdown. How should I customize the dropdown (e.g. background color, dropdown width)? I can change the style property in both DropdownButton and DropdownMenuItem, like this:

return new DropdownButton(
      value: ...,
      items: ...,
      onChanged: ...,
      style: new TextStyle(
        color: Colors.white,
      ),
    );

but this doesn't change the dropdown's background color.

Should I copy DropdownMenu and extend it? Does Flutter plan to add customization for this widget in the near future?

3条回答
一夜七次
2楼-- · 2020-03-01 08:06

I was able to change the background for the Dropdown by wrapping it in a Container with the color property set.

Before:

enter image description here

After:

enter image description here

Here's the code:

Container(
  padding:
      EdgeInsets.symmetric(horizontal: 10, vertical: 5),
  decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(10)),

  // dropdown below..
  child: DropdownButton<String>(
      value: dropdownValue,
      icon: Icon(Icons.arrow_drop_down),
      iconSize: 42,
      underline: SizedBox(),
      onChanged: (String newValue) {
        setState(() {
          dropdownValue = newValue;
        });
      },
      items: <String>[
        'One',
        'Two',
        'Three',
        'Four'
      ].map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(value),
        );
      }).toList()),
)
查看更多
兄弟一词,经得起流年.
3楼-- · 2020-03-01 08:07

You can accomplish this by wrapping the DropdownButton in a Theme widget and overriding the canvasColor.

screenshot

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  State createState() => new MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  int _value = 42;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Center(
        child: new Theme(
          data: Theme.of(context).copyWith(
            canvasColor: Colors.blue.shade200,
          ),
          child: new DropdownButton(
            value: _value,
            items: <DropdownMenuItem<int>>[
              new DropdownMenuItem(
                child: new Text('Foo'),
                value: 0,
              ),
              new DropdownMenuItem(
                child: new Text('Bar'),
                value: 42,
              ),
            ],
            onChanged: (int value) {
              setState(() {
                _value = value;
              });
            },
          ),
        ),
      ),
    );
  }
}
查看更多
老娘就宠你
4楼-- · 2020-03-01 08:15

As Collin said, your DropdownMenuItem will follow your ThemeData class. Not only its backgroundColor will match the canvasColor in your ThemeData class, but also it will follow the same TextStyle.

So, for a quick example:

new ThemeData(
        fontFamily: "Encode Sans", //my custom font
        canvasColor: _turquoise, //my custom color
//other theme data)

Furthermore, if you want to control the width of the menu, you can feed its child property a new Container and add the desired width, check the following GIF, I started with width: 100.0 then hot reloaded after changing it to 200.0, notice how the width was manipulated, just make sure you use a suitable width so that you do not get overflow problems later on when you use the menu within a more complex layout.

enter image description here

class TestPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title:new Text ("Test"),
      ),
      body: new Center(
        child: new DropdownButton(items: new List.generate(20, (int index){
          return new DropdownMenuItem(child: new Container(
            child: new Text ("Item#$index"),
            width: 200.0, //200.0 to 100.0
          ));
        })
            , onChanged: null)
      ),
    );
  }
}
查看更多
登录 后发表回答