Reputation: 6134
I have a dropdown that display a list of strings. The values of the strings contain words that only consists of four letters and words that consists of many letters. This gives a layout problem when the selected item is the one with four letters. An empty or white space can be seen between the text and the trailing icon of the dropdown button. How can this be empty space be removed? How do I adjust the size of the dropdown button depending on the value selected?
Photo of Empty Space between text and trailing icon:
List:
List<String> textList = ["test", "this_is_a_long_text"];
Dropdown:
DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: true,
child: DropdownButton<String>(
items: textList.map((String dropDownStringItem) {
return DropdownMenuItem<String>(
value: dropDownStringItem,
child: Text(dropDownStringItem),
);
}).toList(),
onChanged: (String newValueSelected) {
_onDropDownItemSelected(newValueSelected);
},
value: _currentItemSelected,
),
)),
Upvotes: 8
Views: 10516
Reputation: 16
With property alignment
in DropdownButton you can put de Text centerRight
and make the desire effect.
Test on Flutter 2.12
DropdownButton<String>(
value: dropdownValue,
elevation: 16,
underline: const SizedBox(),
isDense: true,
alignment: Alignment.centerRight,
)
Upvotes: 0
Reputation: 511
Checkout DropdownButton2
There is a customButton property. An example of how I've used it.
customButton: Row(
children: [
const Icon(
Icons.plus_one,
size: 12,
),
Text(
"References",
)
],
),
The option box expands to fit the size of the row.
EDIT: Upon posting this I realize that its still constrained to not being able to have a smaller box compared to items inside
Upvotes: 1
Reputation: 1
With flexfit.loose
the remaining space from the dropdownbutton(comes from a stack inside this widget) will be cutted
Row(
children: [
Flexible(
fit: FlexFit.loose,
child: Padding(
padding: const EdgeInsets.all(8),
child: Container(
decoration: BoxDecoration(
border: Border.all(
width: 2,
color: Theme.of(context).primaryColor,
),
),
child: Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8),
child: DropdownButton(
icon: const Icon(Icons.filter_alt),
underline: Container(),
hint: const Text(
'Test',
style: TextStyle(
color: Colors.black,
),
),
items: const [],
),
),
),
),
),
])
Upvotes: 0
Reputation: 1869
Another work around is to make it a clickable text that will show the dropdown options as a dialog. Here is an example:
import 'package:flutter/material.dart';
class CustomDialogTest extends StatefulWidget {
@override
_CustomDialogTestState createState() => _CustomDialogTestState();
}
class _CustomDialogTestState extends State<CustomDialogTest> {
String _onDropDownItemSelected = '(Choose Option ▼)';
var textList = [
'Cat',
'Dog',
'Colorfull Unicorn',
];
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
title: Text(
'Dropdown spacing',
),
),
body: Padding(
padding: EdgeInsets.only(top: 8.0),
child: Container(
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'I am a ',
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.w500,
),
),
InkWell(
onTap: () {
showDialog(
context: context,
child: Dialog(
backgroundColor: Colors.blue[100],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
),
child: ListView.builder(
shrinkWrap: true,
itemCount: textList.length,
itemBuilder: (context, index) {
return GestureDetector(
child: Row(
children: <Widget>[
Icon(
Icons.arrow_right,
color: Colors.black,
),
Text(
textList[index],
style: TextStyle(
color: Colors.black,
fontSize: 20.0,
),
),
],
),
onTap: () {
Navigator.pop(context);
setState(() {
_onDropDownItemSelected = textList[index];
});
},
);
}),
),
);
},
child: Text(
_onDropDownItemSelected,
style: TextStyle(
color: Colors.blue[900],
fontSize: 18,
fontWeight: FontWeight.w500,
),
),
),
Text(
' Person',
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.w500,
),
),
],
),
),
),
);
}
}
Upvotes: 2
Reputation:
as an option you can build it based on PopupMenuButton
instead of regular DropdownButton
below an example
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(child: AwesomeDropdown()),
),
);
}
}
class AwesomeDropdown extends StatefulWidget {
@override
_AwesomeDropdownState createState() => _AwesomeDropdownState();
}
class _AwesomeDropdownState extends State<AwesomeDropdown> {
final List<String> textList = ["test", "this_is_a111111_long_text"];
String _currentItemSelected;
@override
void initState() {
super.initState();
_currentItemSelected = textList[0];
}
@override
Widget build(BuildContext context) {
return PopupMenuButton<String>(
itemBuilder: (context) {
return textList.map((str) {
return PopupMenuItem(
value: str,
child: Text(str),
);
}).toList();
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(_currentItemSelected),
Icon(Icons.arrow_drop_down),
],
),
onSelected: (v) {
setState(() {
print('!!!===== $v');
_currentItemSelected = v;
});
},
);
}
}
Upvotes: 19
Reputation: 1401
You can't. If you look at the code
// The width of the button and the menu are defined by the widest
// item and the width of the hint.
Clone the widget and change it to your requirements if you have to (not recommended as you'd have to maintain it when the underlining code changes).
Upvotes: 0