Related
I want to add some text validation to my CupertinoTextField but there's no validator for this Widget. How can I solve this?
I tried searching on the internet for some solutions but nothing came out.
CupertinoTextField(
prefix: Padding(
padding: EdgeInsets.all(8.0),
child: Icon(
customIcon,
),
),
style: TextStyle(
fontSize: 30,
),
keyboardType: TextInputType.number,
maxLength: maxLength,
maxLines: 1,
maxLengthEnforced: true,
placeholder: placeholderText,
onChanged: onChangedFunction,
decoration: BoxDecoration(
border: Border.all(
width: 2.0,
color: CupertinoColors.inactiveGray,
),
borderRadius: BorderRadius.circular(32.0),
),
)
You need to use TextEditingController & perform the validation manually.
Basic validation for checking if the field is empty or not.
code:
TextEditingController _myPhoneField = TextEditingController();
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
if (_myPhoneField.text.isEmpty) {
showCupertinoDialog(
context: context,
builder: (context) {
return CupertinoAlertDialog(
title: Text('error'),
content: Text('Phone Field is Empty'),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('ok'))
],
);
});
} else {
// Validation passed
}
},
child: Text('submit'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CupertinoTextField(
clearButtonMode: OverlayVisibilityMode.editing,
controller: _myPhoneField, // Add this
prefix: Padding(
padding: EdgeInsets.all(8.0),
child: Icon(
CupertinoIcons.phone_solid,
),
),
style: TextStyle(
fontSize: 30,
),
keyboardType: TextInputType.number,
maxLength: 10,
maxLines: 1,
maxLengthEnforced: true,
placeholder: 'Enter Phone',
onChanged: (v) {
print(v);
},
decoration: BoxDecoration(
border: Border.all(
width: 2.0,
color: CupertinoColors.inactiveGray,
),
borderRadius: BorderRadius.circular(32.0),
),
),
],
),
);
}
This is not about CupertinoTextField, but if you still want to validate input on Cupertino, you can use the CupertinoTextFormFieldRow widget.
CupertinoTextFormFieldRow(
controller: _usernameController,
validator: (value) {
if (value!.isEmpty || value.length < 4) {
return 'Please enter a valid username.';
}
return null;
},
decoration: BoxDecoration(
color: Colors.black12,
border: Border.all(
color: Colors.black12,
),
borderRadius: BorderRadius.circular(8.0),
),
)
I developed like this dropdown. Everything working fine. By default, the dropdown is not select any value. How to set red color border or something like decoration on value equal null(without select).
my dropdown code and image
Align(
alignment: Alignment.bottomLeft,
child: Container(
child: Text('Priority',
style: TextStyle(fontWeight: FontWeight.w400)),
),
),
// dropBox(),
Container(
// width: 200.0,
child: ButtonTheme(
alignedDropdown: true,
child: DropdownButton<Priority>(
isExpanded: true,
value: _priorities,
//hint: Text("Select"),
items: priority.map((Priority value) {
return DropdownMenuItem<Priority>(
value: value,
child: Text(
value.description,
overflow: TextOverflow.ellipsis,
),
);
}).toList(),
onChanged: (value) => setState(() {
priorityIndex = value.id;
_priorities = value;
}),
style: Theme.of(context).textTheme.title,
),
),
),
I need to like this dropdown,
You are almost there already. You have wrapped your DropdownButton with a Container - now you only have to set its decoration property in order to achieve your desired styling:
return Container(
decoration: BoxDecoration(
border: Border.all(color: _priorities != null ? Colors.red : Colors.transparent),
),
child: DropdownButton(
...
How can I remove the underline from DropdownButtonFormField (check photo below), I have tried various combinations of options with InputDecortaion couldn't find any way.
SizedBox(
width: 100.0,
child: DropdownButtonFormField<int>(
decoration: InputDecoration(
border: UnderlineInputBorder(
borderSide:
BorderSide(color: Colors.white))),
value: 2,
items: <DropdownMenuItem<int>>[
DropdownMenuItem<int>(
value: 1,
child: Text("Owner"),
),
DropdownMenuItem<int>(
value: 2,
child: Text("Member"),
),
],
),
Just wrap DropdownButton inside DropdownButtonHideUnderline like this :
new DropdownButtonHideUnderline(
child: DropdownButton()
)
Setting the underline property to SizedBox() makes it invisible too:
...
DropdownButton(
underline: SizedBox(),
...
One way of Doing it :
In your Code - change decoration: InputDecoration to decoration: InputDecoration.collapsed
body: SizedBox(
width: 100.0,
child: DropdownButtonFormField<int>(
decoration: InputDecoration.collapsed(hintText: ''),
value: 2,
...
OR
In your Code - instead of border Use enabledBorder: UnderlineInputBorder
DropdownButtonFormField<int>(
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white))),
value: 2,
items: <DropdownMenuItem<int>>[
....
The proper/clean solution nowadays is to use InputBorder.none:
DropdownButtonFormField<int>(
decoration: InputDecoration(
enabledBorder: InputBorder.none,
...
),
...
)
You might also want to set border, focusedBorder, errorBorder, and disabledBorder to InputBorder.none if you want to avoid the border from showing in all cases.
underline can take a widget so, you just have assigned it an empty Container, or a SizedBox.shrink()
underline:Container(),
-- or --
underline:SizedBox.shrink(),
Example :
child: DropdownButton<String>(
// Just have to assign to a empty Container
underline:Container(),
value: dropdownValue,
icon: Icon(Icons.keyboard_arrow_down),
iconSize: 24,
elevation: 16,
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
items:[
deptList[0].dept,
deptList[1].dept,
deptList[2].dept,
deptList[3].dept,
].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
)
Add underline: Container() to your settings like this:
SizedBox(
...
underline: Container(),
),
According to this [Flutter Doc] You can do like this. Simply create an object of DropdownButtonHideUnderline class and pass your current implementation of the DropdownButton as the child of DropdownButtonHideUnderline. Thts it ;)
DropdownButtonHideUnderline(
child: new DropdownButton<String>(
......
),
),
As of now, DropdownButtonFormField doesn't support DropdownButtonHideUnderline.
Although it uses it under the hood to remove the underline from DropdownButton but then applies it's own decoration on top of that
Setting border to InputBorder.none will do the job
DropdownButtonFormField<String>(
decoration: InputDecoration(border: InputBorder.none)
)
If you want the border to appear on error you can use
InputDecoration(
border: InputBorder.none,
errorBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
),
You can change underline property to blank or null widget it will work like charm check the below property
underline: widget or SizedBox(),
Ex:-
DropdownButton(
icon: Icon(Icons.more_vert),
isExpanded: true,
value: dropValue,
underline: widget or SizedBox(),
use
DropdownButton<String>(
hint: Text("Status"),
value: 'Text Default',
isExpanded: true,
iconSize: 30,
underline: Container(
height: 1.0,
decoration: const BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.transparent, width: 0.0))
),
),
...
Easy Way to do it
DropdownButtonFormField<String>(
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
),
),
...
)
DropdownButtonHideUnderline(
child: DropdownButton(
isExpanded: true,
hint: Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Select State"),
),
style: MyStyle().getTextStyle("x1black"),
items: <String>[
'Messaging',
'Chating',
'No Longer Interested',
'Document Request'
].map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (_) {},
),
),
Underline takes a Widget. Pass it a blank widget, like below.
DropdownButton<T>(
value: value,
underline: SizeBox(), // Empty box will remove underline
)
You could try the following code:
decoration: InputDecoration(
border: InputBorder.none,
)
To disable every border on the width, set InputBorder.none for border attribute. Or if you prefer to disable only the border when dropdown is enable, set for enabledBorder.
if DropdownButtonFormField text get trim due to outline border then use this code:
DropdownButtonFormField<String>(
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white)),
isDense: true,)
DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: false,
splashColor: Colors.grey,
child: DropdownButton<String>(
value: _myPargna,
iconSize: 25,
icon: Icon(Icons.arrow_drop_down),
style:
TextStyle(fontSize: 18, color: Color(0xFF1f193d)),
hint: Row(
children: [
SizedBox(width: 11),
Text(
'Select Province',
style: TextStyle(color: Colors.grey),
),
],
),
onChanged: (String newValue) {
setState(() {
_myPargna = newValue;
});
},
items: items.map((String items) {
return DropdownMenuItem(
child: Row(
children: [
SizedBox(width: 12),
Text(
items,
style: TextStyle(color: Colors.black),
),
],
),
value: items,
);
}).toList(),
),
),
),
You can just Do this
decoration: const InputDecoration(
// enabledBorder: InputBorder.none,
// disabledBorder: InputBorder.none,
// focusedBorder: InputBorder.none,
// errorBorder: InputBorder.none,
border: InputBorder.none,
),
DropdownButtonFormField(
iconSize: 30,
decoration: InputDecoration(enabledBorder: InputBorder.none),
hint: Text(
"Select Duration",
style: TextStyle(fontSize: 20),
),
items: listDrop,
onChanged: (value) {
duration = value;
},
)
if you want just disable the border in all the case you can use :
DropdownButtonFormField(
validator: _validator,
decoration: InputDecoration(
border: InputBorder.none,
),
items: [],
onChanged: (value) {}),
),
if you want disable only when there is no error you can use this
decoration: InputDecoration(
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent)),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(2.0),
borderSide: BorderSide(color: kLightBlackColor)),
),
This worked for me
DropdownButtonFormField<String>(decoration: InputDecoration(border: InputBorder.none),)
I am pretty new to Flutter and Dart and I can't seem to find any hints for this particular topic. I am trying to put 3 RadioListTiles in a Row like so:
Row(
children: [
Expanded(
child:RadioListTile<GoalSelection>(
title: Text(
'Net',
style: Theme.of(context).textTheme.body1,
),
value: GoalSelection.net,
groupValue: _goalSelection,
onChanged: (GoalSelection value) {
setState(() {
_goalSelection = value;
});
},
),
),
Expanded(
child: RadioListTile<GoalSelection>(
title: Text(
'Gross',
style: Theme.of(context).textTheme.body1,
),
value: GoalSelection.gross,
groupValue: _goalSelection,
onChanged: (GoalSelection value) {
setState(() {
_goalSelection = value;
});
},
),
),
Expanded(
child: RadioListTile<GoalSelection>(
title: Text(
'Salary',
style: Theme.of(context).textTheme.body1,
),
value: GoalSelection.salary,
groupValue: _goalSelection,
onChanged: (GoalSelection value) {
setState(() {
_goalSelection = value;
});
},
),
),
],
),
The buttons layout fine, but there seems to be a lot of wasted space for the label. I put a screenshot of what it currently looks like below. I have tried wrapping the Expanded, the RadioListTile, and the Text in Padding widgets (all one at a time) to manually set the padding to 0, but it didn't do anything. I have also tried to change Expanded to Flexible even though I didn't think that would change anything. I am at a loss now. Is there any way to get this layout to work? I am kind of assuming it is something really dumb that I am doing.
You can use Radio + text widget instead of RadioListTile. For removing internal padding in Radio widget set:
Radio(
visualDensity: const VisualDensity(
horizontal: VisualDensity.minimumDensity,
vertical: VisualDensity.minimumDensity),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
.....
),
You can use a Radio and Text widget in a row. But the Radio also has the same padding problem. To remove the padding you can put the Radio as a child of a SizedBox.
eg:- SizedBox(height: 20, width: 20, child: Radio(.......))
RadioListTile is used with the purpose of taking the full width in a vertical scroll list.
If you don't want this behavior, don't use it. Use Radio instead.
just set contentPadding: EdgeInsets.zero
RadioListTile(contentPadding: EdgeInsets.zero)
We can control the padding of the RadioListTile using Flexible widget. As you want to arrange 3 RadioListTiles inside a Row Widget. Please try with the below code, it will work.
Row(
children: <Widget>[
Flexible(
fit: FlexFit.loose,
child:
RadioListTile(
title: const Text('hello'),
onChanged: (value) {
setState(() {});
},
),
),
Flexible(
fit: FlexFit.loose,
child:
RadioListTile(
title: const Text('Lafayette'),
onChanged: (value) {
setState(() {});
},
),
)
],
),
Do, let me know. Once you tried with the above code. If it resolved you problem, please accept my answer as useful and provide your valuable comments.
I got the same problem. You could try to customize with Radio, Text, InkWell, Padding.
class LabeledRadio extends StatelessWidget {
const LabeledRadio({
this.label,
this.padding,
this.groupValue,
this.value,
this.onChanged,
});
final String label;
final EdgeInsets padding;
final bool groupValue;
final bool value;
final Function onChanged;
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
if (value != groupValue)
onChanged(value);
},
child: Padding(
padding: padding,
child: Row(
children: <Widget>[
Radio<bool>(
groupValue: groupValue,
value: value,
onChanged: (bool newValue) {
onChanged(newValue);
},
),
Text(label),
],
),
),
);
}
}
// ...
bool _isRadioSelected = false;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <LabeledRadio>[
LabeledRadio(
label: 'This is the first label text',
padding: const EdgeInsets.symmetric(horizontal: 5.0),
value: true,
groupValue: _isRadioSelected,
onChanged: (bool newValue) {
setState(() {
_isRadioSelected = newValue;
});
},
),
LabeledRadio(
label: 'This is the second label text',
padding: const EdgeInsets.symmetric(horizontal: 5.0),
value: false,
groupValue: _isRadioSelected,
onChanged: (bool newValue) {
setState(() {
_isRadioSelected = newValue;
});
},
),
],
),
);
}
The documentation: https://api.flutter.dev/flutter/material/RadioListTile-class.html#material.RadioListTile.3
This is how I fix the padding:
enum ContactSex { nam, nu, khac }
class CreateContactScreen extends StatefulWidget {
static const routeName = './create_contact';
#override
_CreateContactScreenState createState() => _CreateContactScreenState();
}
class _CreateContactScreenState extends State<CreateContactScreen> {
ContactSex _contaxtSex = ContactSex.nu;
final _form = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'TẠO LIÊN HỆ',
style: kHeaderTextStyle,
),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('XONG', style: TextStyle(color: Colors.white),),
)
],
),
body: Container(
padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 20.0),
child: Form(
key: _form,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(
labelText: 'Tên*',
),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
// TODO: when submit this text field
},
validator: (value) {
if (value.isEmpty) {
return 'Hãy nhập tên cho liên hệ.';
}
return null;
},
onSaved: (value) {
// TODO : when save the whole form
},
),
TextFormField(
decoration: InputDecoration(
labelText: 'Họ',
),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
// TODO: when submit this text field
},
// validator: (value) {
// if (value.isEmpty) {
// return null;
// }
// return null;
// },
onSaved: (value) {
// TODO : when save the whole form
},
),
TextFormField(
decoration: InputDecoration(
labelText: 'Số điện thoại*',
),
keyboardType: TextInputType.phone,
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
// TODO: when submit this text field
},
validator: (value) {
if (value.isEmpty) {
return 'Hãy nhập số điện thoại cho liên hệ.';
}
return null;
},
onSaved: (value) {
// TODO : when save the whole form
},
),
TextFormField(
decoration: InputDecoration(
labelText: 'Email',
),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
// TODO: when submit this text field
},
// validator: (value) {
// if (value.isEmpty) {
// return null;
// }
// return null;
// },
onSaved: (value) {
// TODO : when save the whole form
},
),
Container(
padding: EdgeInsets.only(top: 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Giới tính',
style: TextStyle(fontSize: 14.0),
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
LabeledRadio(
label: 'Nữ',
padding: EdgeInsets.all(0),
groupValue: _contaxtSex,
value: ContactSex.nu,
onChanged: (ContactSex newValue) {
setState(() {
_contaxtSex = newValue;
});
},
),LabeledRadio(
label: 'Nam',
padding: EdgeInsets.all(0),
groupValue: _contaxtSex,
value: ContactSex.nam,
onChanged: (ContactSex newValue) {
setState(() {
_contaxtSex = newValue;
});
},
),LabeledRadio(
label: 'Khác',
padding: EdgeInsets.all(0),
groupValue: _contaxtSex,
value: ContactSex.khac,
onChanged: (ContactSex newValue) {
setState(() {
_contaxtSex = newValue;
});
},
),
],
),
],
),
)
],
)),
),
),
);
}
}
class LabeledRadio extends StatelessWidget {
final String label;
final EdgeInsets padding;
final ContactSex groupValue;
final ContactSex value;
final Function onChanged;
const LabeledRadio(
{this.label, this.padding, this.groupValue, this.value, this.onChanged});
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
if (value != groupValue) {
onChanged(value);
}
},
child: Padding(
padding: padding,
child: Row(
children: <Widget>[
Radio<ContactSex>(
groupValue: groupValue,
value: value,
onChanged: (ContactSex newValue) {
onChanged(newValue);
},
),
Text(label),
],
),
),
);
}
}
You just need to set the "dense" property to true, example:
RadioListTile<String>(
title: "My radio",
dense: true, // <= here it is !
value: '1',
);
you should achieve this manually like
make a group of Radio() and Text() and wrap with InkWell() for state handling. now remove extra space of radio by materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, That's it. Get idea by sample code.
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
setState(() {
_radioVenue = 0;
});
},
child: Row(
children: [
Radio(
materialTapTargetSize:
MaterialTapTargetSize.shrinkWrap,
activeColor: primaryColor,
groupValue: _radioVenue,
onChanged: (value) {},
value: 0,
),
Text('From our list')
],
),
),
InkWell(
onTap: () {
setState(() {
_radioVenue = 1;
});
},
child: Row(
children: [
Radio(
materialTapTargetSize:
MaterialTapTargetSize.shrinkWrap,
activeColor: primaryColor,
groupValue: _radioVenue,
onChanged: (value) {},
value: 1,
),
Text('From our list')
],
),
),
],
),
We covered both both the issues in this sample.
Removed extra spaces.
whole group is selectable radio + text, Now it behaves like RadioListTile().
Simply use RadioListTile and remove extra padding, by default it's 18
RadioListTile(contentPadding: EdgeInsets.symmetric(horizontal: 0.0)),
OR
RadioListTile(
contentPadding: EdgeInsets.symmetric(horizontal: 0.0),
value: null,
groupValue: null,
onChanged: null,
),
glad to answer
I was looking for same question and ended up on Flutter Documentation
I was working on Column and RadioListTile and I faced same issue, there's a horizontal padding between content inside RadioListTile
So, here it's the answer
Looking for this documentation ! RadioListTile content padding
Just add contentPadding: EdgeInsets.symmetric(horizontal: 0) and here you go, there's no horizontal padding anymore
Just copy paste this code and enjoy
Container(
height:35,
child: Row(
children: [
Radio(
groupValue: data.selected,
value: e,
onChanged: (DataBindModel? value) {
listener.value = MultiChoiceData(selected: value, items: listener.value.items);
onChanged(value);
onSelected(value);
},
),
Text(
e.value,
style: body14,
)
],
),
)
Copy the RadioListTile code and create your on new new file and paste it in there.
Remove the imports causing errors:
import 'package:flutter/widgets.dart'; // leave it
import 'package:flutter/material.dart'; //add
import 'list_tile.dart'; //remove
import 'radio.dart'; //remove
import 'theme.dart'; //remove
import 'theme_data.dart'; //remove
Then add the following padding to it, like this:
//Inside the file locate this widget and Add the padding or remove it. I needed to remove it and add 5.
return MergeSemantics(
child: ListTileTheme.merge(
contentPadding: EdgeInsets.only( // Add this
left: 5,
right: 0,
bottom: 0,
top: 0
),
selectedColor: activeColor ?? Theme.of(context).accentColor,
child: ListTile(
leading: leading,
title: title,
subtitle: subtitle,
trailing: trailing,
isThreeLine: isThreeLine,
dense: dense,
enabled: onChanged != null,
onTap: onChanged != null && !checked ? () { onChanged(value); } : null,
selected: selected,
),
),
);
then Import the file into your project like this:
import 'package:Project_Name/common/customComponets/custom_radio_list_tile.dart' as CustomRadioListTile;
Then use it like this:
CustomRadioListTile.RadioListTile(); // and that's how I managed to do it. Thought I should share.
This is my way of reducing the space. I have three Radio in one row.
Row(
children: [
Expanded(
child: RadioListTile(
contentPadding: EdgeInsets.all(0.0),
value: DayoffType.Range,
groupValue: _dayoffType,
title: Transform.translate(offset: const Offset(-18, 0), child: Text('Range')),
onChanged: (DayoffType? val) {
setState(() {
_dayoffType = val!;
});
},
),
),
Expanded(...Radio2...),
Expanded(...Radio3...)
)
I am creating below registration form in Flutter.
TextStyle white =
new TextStyle(color: Colors.white, decorationColor: Colors.white);
TextStyle grey =
new TextStyle(color: Colors.grey, decorationColor: Colors.white);
I want to apply white style to DropDownButton and grey to DropDownMenuItem.
But, the style of DropDownMenu item is also applied to DDButton.
Also, can I "match_parent" the width of DropDownButton like TextField (as in image)?
Here is the code:
child: new Center(
child: new ListView(
shrinkWrap: true,
padding: new EdgeInsets.only(left: 24.0, right: 24.0),
children: <Widget>[
new ListTile(
leading: const Icon(
Icons.language,
color: Colors.white,
),
title: new DropdownButton(
items:
<String>['India', 'Australia', 'USA'].map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value, ),
);
}).toList(),
value: selected,
onChanged: (String value) {
setState(() {
selected = value;
});
},
style: white,
),
),
new ListTile(
leading: const Icon(Icons.smartphone, color: Colors.white),
title: new TextField(
decoration: new InputDecoration(
hintText: "Phone Number", hintStyle: white),
keyboardType: TextInputType.phone,
style: white,
),
),...
There is the final bool inherit property at the TextStyle Class, you can try something like this:
TextStyle white =
new TextStyle(inherit: false, color: Colors.white, decorationColor: Colors.white);
You can do that using selectedItemBuilder property of the dropdown the issue as of now with that is you cannot use a hintText and selectedItemBuilder together. you can track the open issue here.
But Theres a temporary workaround for this is to use one of them based on the selected dropdownValue
DropdownButton<String>(
value: dropdownValue,
style: TextStyle(color: Colors.grey, fontSize: 15),
hint: dropdownValue != null
? null
: Text(
'Select Value',
style: TextStyle(color: Colors.black),
),
onChanged: (value) => setState(() => dropdownValue = value),
selectedItemBuilder: dropdownValue == null
? null
: (BuildContext context) {
return ['ONE', 'TWO.', 'THREE'].map((String value) {
return Text(
dropdownValue,
style: TextStyle(color: Colors.green),
);
}).toList();
},
items: ['ONE', 'TWO.', 'THREE']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value,
style: TextStyle(inherit: false, color: Colors.red)),
);
}).toList(),
),
you can find a dartpad example here
Add isExpanded in DropdownButton.
DropdownButton(
isExpanded: true,
)
Checkout DropDownButton2 for easy customized styling
For more examples and to know more about the package follow this link: DropDownButton2