Reputation: 20495
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?
Upvotes: 67
Views: 159854
Reputation: 1196
I am using following class
import 'package:flutter/material.dart';
import 'package:safe/utils/app_ui.dart';
class LabeledDropdown<T> extends StatefulWidget {
final String heading;
final List<DropdownMenuItem<T>> items;
final T? value;
final ValueChanged<T?> onChanged;
const LabeledDropdown({
super.key,
required this.heading,
required this.items,
required this.value,
required this.onChanged,
});
@override
State<LabeledDropdown<T>> createState() => _LabeledDropdownState<T>();
}
class _LabeledDropdownState<T> extends State<LabeledDropdown<T>> {
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(widget.heading, style: const TextStyle(fontSize: 14)),
const SizedBox(height: 8),
DropdownButtonFormField<T>(
decoration: InputDecoration(
fillColor: Colors.white, // Background color
filled: true, // Enable filling
border: OutlineInputBorder(
borderSide: BorderSide.none, // Remove border
borderRadius: BorderRadius.all(
Radius.circular(cornerRadius),
), //set border radius
),
),
value: widget.value,
items: widget.items,
onChanged: widget.onChanged,
hint: const Text("Select an option"),
),
],
);
}
}
no need to wrap DropdownButtonFormField
inside a Container
to set borders and change the background color...
you can set the fillColor
and filled
properties to change the background color ...
you can use this
child: LabeledDropdown<String>(
heading: 'District*',
items:
_options.map((option) {
return DropdownMenuItem<String>(
value: option,
child: Text(option),
);
}).toList(),
value: _selectedValue,
onChanged: (value) {
setState(() {
_selectedValue = value;
});
},
),
where options are
final List<String> _options = [
'Option One',
'Option two',
'Option three',
'Option four',
];
and here are the end result
Upvotes: 0
Reputation: 21
I recently upgraded my Flutter SDK from version 3.0.0 to 3.22.2, and I noticed that the background color of my DropdownButtonFormField has changed automatically. I did not make any changes to the code, and it was working perfectly before the upgrade. Below is my code for the
please suggest me best solution for the Dropdown background color
DropdownButtonFormField:
DropdownButtonFormField<String>(
decoration: const InputDecoration(
fillColor: Colors.transparent,
filled: true,
contentPadding: EdgeInsets.only(right: 10, left: 10),
border: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xFFE6E5E9), width: 1),
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xFF09304B), width: 1),
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xFFE6E5E9), width: 1),
borderRadius: BorderRadius.all(
Radius.circular(10.0),
),
),
),
elevation: 1,
validator: (value) {
print("sdfds");
},
isExpanded: true,
hint: const Text(
"Select Payment Purpose*",
style: TextStyle(
color: Color(0xFF0F0F18),
fontWeight: FontWeight.w400,
fontFamily: 'inter',
fontSize: 14,
),
),
iconSize: 30,
iconEnabledColor: Colors.black,
icon: const Icon(
Icons.keyboard_arrow_down_sharp,
size: 20,
),
value: selectedValue,
items: Constants.transactionPurposeList
.map<DropdownMenuItem<String>>((TransactionPurposeList value) {
return DropdownMenuItem<String>(
value: value.name!,
child: Text(value.name!),
);
}).toList(),
onChanged: (value) {
setState(() {
selectedValue = value;
isSelectPurpose = false;
});
},
)
transactionPurposeList access from Rest API
Upvotes: 0
Reputation: 11
To create own custom drop down widget you can use below code value - selected dropdown value items - list of dropdownitem you can pass onChanged - pass function that will be invoked when you select from dropdown
import 'package:flutter/material.dart';
class SDropDown extends StatefulWidget {
final String value;
final List<DropdownMenuItem<String>> items;
final Function(String?)? onChanged;
const SDropDown[enter image description here][1](
{Key? key, required this.value, required this.items, this.onChanged})
: super(key: key);
@override
_SDropDownState createState() => _SDropDownState();
}
class _SDropDownState extends State<SDropDown> {
@override
Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
return Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 3),
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(10)),
child: DropdownButton<String>(
isExpanded: true,
value: widget.value,
items: widget.items,
onChanged: widget.onChanged,
underline: const SizedBox(),
dropdownColor: theme.primaryColor,
style: const TextStyle(color: Colors.black),
),
);
}
}
Upvotes: 1
Reputation: 21
you can use the dropdown_button2 package. You can use the dropdownDecoration property to customize the dropdown menu appearance. This is the best package I found to fully customize a DropdownButton
Upvotes: 2
Reputation: 7065
I was able to change the background for the Dropdown by wrapping it in a Container
with the color
property set.
Before:
After:
Here's the code:
Define these values in the widget state:
final items = ['One', 'Two', 'Three', 'Four'];
String selectedValue = 'Four';
then use this code
Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(10)),
// dropdown below..
child: DropdownButton<String>(
value: selectedValue,
onChanged: (String newValue) =>
setState(() => selectedValue = newValue),
items: items
.map<DropdownMenuItem<String>>(
(String value) => DropdownMenuItem<String>(
value: value,
child: Text(value),
))
.toList(),
// add extra sugar..
icon: Icon(Icons.arrow_drop_down),
iconSize: 42,
underline: SizedBox(),
),
);
Upvotes: 70
Reputation: 1019
https://api.flutter.dev/flutter/material/DropdownButton/style.html will help you to figure out some stylings.
DropdownButton(
dropdownColor: Colors.grey,
value: this.repeatType,
onChanged: (String? value) {
print(value);
setState(() {
this.repeatType = value!;
});
},
selectedItemBuilder: (BuildContext context) {
return this.repeatTypes.map((String value) {
return Text(
this.repeatType,
style: const TextStyle(color: Colors.white),
);
}).toList();
},
items: this
.repeatTypes
.map((item) => DropdownMenuItem(
child: Text(
item,
style: TextStyle(color: Colors.green),
),
value: item,
))
.toList())
Upvotes: 4
Reputation: 6284
You can wrap it with container like this:
Container(
margin: const EdgeInsets.all(15.0),
padding: const EdgeInsets.only(left: 10.0, right: 10.0),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.white)
),
child: DropdownButton(
dropdownColor: Colors.white,
style: TextStyle(
color: Colors.black,
backgroundColor: Colors.white,
),
value: 'ar',
items: [
DropdownMenuItem(child: Text('English'), value: 'en'),
DropdownMenuItem(child: Text('العربية'), value: 'ar'),
],
),
)
The output:
Upvotes: 4
Reputation: 3059
Use this for color
DropdownButtonFormField(
items: null,
onChanged: null,
dropdownColor: Colors.red,
),
Upvotes: 15
Reputation: 598
You can do something very simple in the latest version of Flutter.
The DropdownButton class has an inbuilt variable called 'dropdownColor' which can be assigned any color you need directly, without changing any 'ThemeData'. Automatically changes the color of the dropdown menu items as well.
Upvotes: 19
Reputation: 233
If you want the DropdownButton to fill the space that it is in, use the property isExpanded
and set it to true
DropdownButton<String>(
isExpanded: true,
)
Upvotes: 15
Reputation: 53347
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.
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)
),
);
}
}
Upvotes: 40
Reputation: 116828
You can accomplish this by wrapping the DropdownButton
in a Theme
widget and overriding the canvasColor
.
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;
});
},
),
),
),
);
}
}
Upvotes: 95