Comments (13)
same idea :)
class MyDropdownButton extends StatefulWidget {
const MyDropdownButton({Key? key}) : super(key: key);
@override
State<MyDropdownButton> createState() => _MyDropdownButtonState();
}
class _MyDropdownButtonState extends State<MyDropdownButton> {
final List<String> customers = [
'Customer 1',
'Customer 2',
];
String? selectedCustomer;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
margin: const EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 0.0),
child: InputDecorator(
decoration: InputDecoration(
filled: true,
fillColor: Colors.teal.shade50,
contentPadding: const EdgeInsets.symmetric(horizontal: 20),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.teal.shade800,
),
),
label: Text(
'Customer',
style: TextStyle(
color: Colors.teal.shade800,
),
),
),
child: DropdownButtonHideUnderline(
child: DropdownButton2<String>(
buttonPadding: const EdgeInsets.symmetric(vertical: 6),
itemPadding: const EdgeInsets.symmetric(horizontal: 20),
dropdownWidth: MediaQuery.of(context).size.width -
(8.0 + 8.0), //L&R container's margin
offset: const Offset(-20, 0),
hint: Text(
'Select customer',
style: TextStyle(
color: Colors.teal.shade800,
),
),
style: const TextStyle(
color: Colors.black,
),
selectedItemBuilder: (context) {
return customers.map((element) {
return Align(
alignment: Alignment.centerLeft,
child: Text(
element,
style: TextStyle(
color: Colors.teal.shade800,
fontWeight: FontWeight.bold,
),
),
);
}).toList();
},
icon: Icon(
Icons.arrow_drop_down,
color: Colors.teal.shade800,
),
items: customers
.map((item) => DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: const TextStyle(
fontSize: 14,
),
),
))
.toList(),
isExpanded: true,
value: selectedCustomer,
onChanged: (value) {
setState(() => selectedCustomer = value);
},
),
),
),
),
),
);
}
}
from dropdown_button2.
When both buttonWidth
& dropdownWidth
is null (not used), their width will be calculated from the maximum width of items or hint text IndexedStack
.
Therefore, MenuHorizontalPadding (itemPadding+dropdownPadding+dropdownScrollPadding) need to be added to that IndexedStack so Both button and menu Adapt to max items width when buttonWidth & dropdownWidth is null.
so that behavior is necessary for another use case not yours. Adding any dropdownWidth
value for your case will prevent adding that default MenuHorizontalPadding. but you need your dropdown menu to be equal to the button which in your case is screen size - 16.0 (right and left margin)
.
from dropdown_button2.
All that tricky work is necessary because of the need to add contentPadding in your case. which is added to the InputDecorator
around the DropdownButton2 so you need to manually consider it with dropdown width too :)
from dropdown_button2.
After having a better clarity on these concepts, I've further finetuned the UI by adding an icon on the left of the DropdownButton2
widget. 'dropdownWidth' had to be made dependent on the width of InputDecorator
this time, instead of the width retrieved from MediaQuery
. Here is the final result:
I must say I've learned a lot about this widget today and I'll be way more confident and comfortable using it in future. Thanks a lot for taking time to explain the underlying concepts and providing a fix suitable to my particular use case.
from dropdown_button2.
Wrap your label
with padding:
label: Padding(
padding: EdgeInsets.only(left: 20.0),
child: Text('hello'),
),
from dropdown_button2.
I've tried this as well but then there is a huge gap between the label and the outline border on the left. It looks even more awkward.
from dropdown_button2.
That's correct.
Well, That's the default behavior of InputDecoration and this is related to flutter.
You can use floatingLabelAlignment to align label to center
instead but It's not possible to set padding for the label without affecting the hint/contents.
from dropdown_button2.
Btw, as you have padding for the contents anyway, why not using contentPadding of left and only use right padding for the hint/contents ?
from dropdown_button2.
Btw, as you have padding for the contents anyway, why not using contentPadding of left and only use right padding for the hint/contents ?
I don't think I understood this properly.
Anyway, here is my content padding in the InputDecorator
-> contentPadding: EdgeInsets.zero,
and here is my button padding in DropdownButton2
-> buttonPadding: const EdgeInsets.fromLTRB(0, 6, 6, 6)
from dropdown_button2.
Can you share a small sample code ?
from dropdown_button2.
Here's an example (hence: contentPadding, itemPadding, dropdownWidth and offset properties):
final List<String> genderItems = [
'Male',
'Female',
];
String? selectedValue;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SizedBox(
width: 300,
child: DropdownButtonFormField2(
decoration: InputDecoration(
isDense: true,
label: const Text("Label"),
contentPadding: const EdgeInsets.symmetric(horizontal: 20),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
),
),
hint: const Text(
'Select Your Gender',
style: TextStyle(fontSize: 14),
),
icon: const Icon(
Icons.arrow_drop_down,
color: Colors.black45,
),
buttonHeight: 60,
itemPadding: const EdgeInsets.only(left: 20),
dropdownWidth: 300,
offset: const Offset(-20, 0),
items: genderItems
.map((item) => DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: const TextStyle(
fontSize: 14,
),
),
))
.toList(),
onChanged: (value) {
//Do something when changing the item if you want.
},
),
),
),
);
}
from dropdown_button2.
Can you share a small sample code ?
I've created this widget as a sample taking the same properties as that in my actual code.
class MyDropdownButton extends StatefulWidget {
const MyDropdownButton({Key? key}) : super(key: key);
@override
State<MyDropdownButton> createState() => _MyDropdownButtonState();
}
class _MyDropdownButtonState extends State<MyDropdownButton> {
final List<String> customers = [
'Customer 1',
'Customer 2',
];
String? selectedCustomer;
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 0.0),
child: Expanded(
child: InputDecorator(
decoration: InputDecoration(
filled: true,
fillColor: Colors.teal.shade50,
contentPadding: EdgeInsets.zero,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.teal.shade800,
),
),
label: Padding(
padding: const EdgeInsets.only(left: 20.0),
child: Text(
'Customer',
style: TextStyle(
color: Colors.teal.shade800,
),
),
),
),
child: DropdownButtonHideUnderline(
child: DropdownButton2<String>(
buttonPadding: const EdgeInsets.fromLTRB(0, 6, 6, 6),
hint: Text(
'Select customer',
style: TextStyle(
color: Colors.teal.shade800,
),
),
style: const TextStyle(
color: Colors.black,
),
selectedItemBuilder: (context) {
return customers.map((element) {
return Align(
alignment: Alignment.centerLeft,
child: Text(
element,
style: TextStyle(
color: Colors.teal.shade800,
fontWeight: FontWeight.bold,
),
),
);
}).toList();
},
icon: Icon(
Icons.arrow_drop_down,
color: Colors.teal.shade800,
),
items: customers
.map((item) => DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: const TextStyle(
fontSize: 14,
),
),
))
.toList(),
isExpanded: true,
value: selectedCustomer,
onChanged: (value) {
setState(() => selectedCustomer = value);
},
),
),
),
),
);
}
}
from dropdown_button2.
Awesome!
As far as I can understand, dropdownWidth
and offset
made all the difference here.
However, just out of curiosity, if in above code, I remove dropdownWidth
and offset
, I get the following result. This is something that I kept struggling with without knowing why the contents of the button ('Select customer', in this case) were being wrongly aligned. Is button's width somehow linked with the dropdownWidth
?
from dropdown_button2.
Related Issues (20)
- Dropdown open Need to open only top and below not in center of widget HOT 3
- How to remove outer padding for dropdown menu HOT 2
- 'dropdownStyleData' isn't defined. HOT 1
- Bug: unable to add Custom Items Heights for Multi Item Select DropDown HOT 8
- When selectedValue is null and the Hint defined, the onChanged event doesn't get triggered HOT 3
- Searchable Dropdown: Not working in release mode HOT 3
- Dropdown SafeArea.
- Either zero or 2 or more items were detected with the same value, and if the first item is not selected the other selections disappear from the button HOT 21
- [feature] Add `DropdownButton2FormField` HOT 1
- Dropdown doesn't open if you don't have onChanged HOT 1
- Remove padding left HOT 1
- Clear button (again) HOT 8
- URGENT! Make selectedItemBuilder return a single Widget and not List<Widget> HOT 3
- Easy way of changing the style of the selected item's text HOT 7
- The getter 'View' isn't defined for the class 'DropdownButton2State<T> HOT 2
- using callTap() with DropdownButtonFormField2 HOT 1
- Search with API HOT 1
- Search Issue in when installing app in real device HOT 8
- Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe. HOT 2
- Bottom line doesn't change color when is focused in desktop application. HOT 9
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dropdown_button2.