How to change FLUTTER DropdownMenuItem's textDirection (change widget direction) - flutter

I need to change widget's textDirection according to the language selection. I have a variable for textDirection in my global translation class and add it to parent widgets. All are work fine except DropdownMenuItems. I tried with wrapping text widget by Directionality widget but still not working as expect.
Ex: when I change language which use rtl items should align to right which
is not happening currently.
return DropdownMenuItem(
child: Directionality(textDirection: Translations.textDirection ,
child: new Text(listItems,textDirection: Translations.textDirection,)
...
Also I tried adding textDirection after wrapped whole DropdownButton with a Container.
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
textDirection: Translations.textDirection,
children: <Widget>[
DropdownButton(
But still not work. What should I do to change the textDirection of DropdownMenuItems ?? Any help would be appreciate.
note: I can't add textDirection to MaterialApp. Need to change it when select different languages.

I Solved it
DropdownButton<String>(
hint: Text(
'City',
style: TextStyle(fontFamily: 'Cairo'),
),
isExpanded: true,
value: dropdownValue,
elevation: 4,
style: TextStyle(
color: Colors.deepPurple, fontFamily: 'Cairo'),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
debugPrint(cityInfo.indexOf(newValue).toString());
});
},
items:
cityInfo.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Container(
alignment: Alignment.centerRight,
child: Text(
value,
),
),
);
}).toList(),
),

For left to right text direction:
Text('MyText', textDirection: TextDirection.ltr,)
OR
For right to left text direction:
Text('MyText', textDirection: TextDirection.rtl)

DropdownButton<String>(
items: <String>['A', 'B', 'C', 'D'].map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Center(
child: Text(value),
),
);
}).toList(),
onChanged: (_) {},
),
Just wrap the DropDownMenuItem child Widget(Text) with a Center widget
Update: Sorry I miss understood it as how to center the widget.
You can add TextDirection.rtl or TextDirection.ltr to textDirection property
If it does not work try wrapping it a Row with mainAxisAlignment to end

use Directionality widget as aparent of the

Related

How to customize the dropdownlist in flutter , like flikart dropdownlist

I want to dropdownlist but i'm not able to do following things.
change the width of the dropdownbutton
make the dropdownlist to start at the dropdownbutton's height , not above it as default
adjust the height of the dropdownmenuitem
Want i want is
What i have is
The code goes like
child: ButtonTheme(
alignedDropdown: true,
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
// isDense: true,
// isExpanded: true,
itemHeight: null,
// menuMaxHeight: 10,
alignment: AlignmentDirectional.center,
elevation: 0,
value: selectedQuantity,
selectedItemBuilder: (BuildContext context) {
return _dropDownQuantities.map<Widget>((String item) {
return Container(
alignment: Alignment.center,
// color: Colors.green,
child: Text(
'Qty: $item',
style: TextStyle(fontSize: 14),
),
);
}).toList();
},
items: _dropDownQuantities.map((e) {
return DropdownMenuItem(
alignment: AlignmentDirectional.topStart,
child: Container(
child: Column(
children: [Container(child: Text(e))],
)),
value: e,
);
}).toList(),
hint: Text("Qty: 1 "),
onChanged: (value) {
setState(() {
selectedQuantity = value!;
});
}),
),
),
Use DropdownButton2 to achieve that.
Use buttonWidth property to change the width of the dropdownbutton.
Use offset property to change the position of the dropdown menu. You should add button's height to the dy offset to make it start at the dropdownbutton's height like this: Offset(0.0, "button's height")
Use itemHeight property to adjust the height of the dropdownmenuitem.
Disclaimer: I am the author of the package mentioned above.

How to disable a specific dropdownmenu item value in flutter

Disable dropDown value in Flutter
policyDropdown = ['Platinum', 'Gold', 'Sr. Citizen'],
child: Container(
height: 50.0,
child: ListTile(
title: Text('Policy Type'),
trailing: DropdownButtonHideUnderline(
child: DropdownButton(
value: policyDropdownData,
items: policyDropdown.map((String value) {
return DropdownMenuItem(
child: Text(value),
value: value,
);
}).toList(),
onChanged: (String? value) {
setState(() {
policyDropdownData = value.toString();
});
},
),
disable the first data of the policyDropdown... What can I do?
You can use the enable property of the DropdownMenuItem and enable every other option than the first one of your policyDropdown list i.e."Platinum".
for example:
return DropdownMenuItem(
value: value,
child: Text(value),
enabled: value != 'Platinum',
);
Additionally, If you want users to know that the option is disabled you can change the color of the text using the same logic.
return DropdownMenuItem(
value: value,
child: Text(
value,
style: TextStyle(
color: value != 'Platinum'
? Colors.white
: Colors.white60,
),
),
enabled: value != 'Platinum',
);

How to remove/reduce space betwen text and checkbox of CheckboxListTile in Flutter?

How can I reduce/remove the space between the CheckboxListTile and the Text in the following image?
It seems the following line removes the surrounding space only.
CheckboxListTile(
title: Text('Account number not available'),
contentPadding: EdgeInsets.all(0),
controlAffinity: ListTileControlAffinity.leading,
)
CheckboxListTile is using ListTile which has the same padding as contentPadding so this is not a problem because you set it to 0.0, but it also has field called visualDensity which you cannot set from CheckboxListTile. This visualDensity is inherited from ThemeData. So either you will set VisualDensity.compact in your theme (you still won't be able to completely remove the space you have highlighted, but it will be smaller, it depends on your current ThemeData settings), or make a custom LabeledCheckbox widget for full flexibility as i did which is not really hard.
Edit:
I am using this custom LabeledCheckbox widget, you can control the gap between CheckBox and Text with field gap, also it is wrapped with GestureDetector so it register tap on the text too, not just the checkbox itself.
class LabeledCheckbox extends StatelessWidget {
const LabeledCheckbox({
this.label,
this.contentPadding,
this.value,
this.onTap,
this.activeColor,
this.fontSize,
this.gap = 4.0,
this.bold = false,
});
final String label;
final EdgeInsets contentPadding;
final bool value;
final Function onTap;
final Color activeColor;
final double fontSize;
final double gap;
final bool bold;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => onTap(!value),
child: Padding(
padding: contentPadding ?? const EdgeInsets.all(0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Checkbox(
value: value,
activeColor: activeColor,
visualDensity: VisualDensity.compact,
onChanged: (val) => onTap(val),
),
SizedBox(
width: gap,
), // you can control gap between checkbox and label with this field
Flexible(
child: Text(
label,
style: TextStyle(
fontSize: fontSize,
fontWeight: bold ? FontWeight.bold : FontWeight.normal,
),
),
),
],
),
),
);
}
}
You can do something like this
ListTileTheme(
horizontalTitleGap: 0,
child: CheckboxListTile(
controlAffinity: ListTileControlAffinity.leading,
title: Text(
title,
style: kRegularFontStyle.copyWith(
fontSize: 16.0.sp,
color: Theme.of(context).textTheme.subtitle1!.color,
),
),
value: isChecked,
onChanged: onChanged,
activeColor: kStructuralBlue500,
checkColor: kWhiteColor,
checkboxShape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4.0.r)),
contentPadding: EdgeInsets.zero,
),
),
I reworked a complete widget inspired by the accepted answer that actually does not work (no state management, null safety, and gesture detector issue).
class LabeledCheckbox extends StatefulWidget {
final String label;
final EdgeInsets? contentPadding;
final bool value;
final Function onTap;
final Color activeColor;
final double fontSize;
final double gap;
final bool bold;
const LabeledCheckbox({
required this.label,
this.contentPadding,
required this.value,
required this.onTap,
this.activeColor = Colors.blueAccent,
this.fontSize = 16.0,
this.gap = 4.0,
this.bold = false,
});
#override
State<LabeledCheckbox> createState() => _LabeledCheckboxState();
}
class _LabeledCheckboxState extends State<LabeledCheckbox> {
late bool _checkboxValue;
#override
void initState() {
_checkboxValue = widget.value;
super.initState();
}
void _updateCheckBox(bool val){
setState(() {
_checkboxValue = val;
// call ontap with new value
widget.onTap(_checkboxValue);
});
}
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () => _updateCheckBox(!_checkboxValue),
child: Padding(
padding: widget.contentPadding ?? const EdgeInsets.all(0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Checkbox(
value: _checkboxValue,
activeColor: widget.activeColor,
visualDensity: VisualDensity.compact,
onChanged: (val){
_updateCheckBox(val??false);
}
),
SizedBox(
width: widget.gap,
), // you can control gap between checkbox and label with this field
Flexible(
child: Text(
widget.label,
style: TextStyle(
fontSize: widget.fontSize,
fontWeight: widget.bold ? FontWeight.bold : FontWeight.normal,
),
),
),
],
),
),
);
}
}
You can find a full working exemple on dartpad
Above All Answers Are Showing Complicated Ways. It's ACTUALLY SIMPLE. Don't use CheckboxListTile. instead use CheckBox with Text in Row with mainAxisSize: MainAxisSize.min as shown in Example Code and set these properties to CheckBox:
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
visualDensity: VisualDensity.compact,
Check This Example Code
Row(
mainAxisSize: MainAxisSize.min,
children: [
Checkbox(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
visualDensity: VisualDensity.compact,
value: true,
onChanged: (newValue){
//Do Something When Value Changes to True Or False
},
),
Text('Account number not available'),
]
)
Final Result
Enjoy!!

How to change height of DropdownButton in flutter

How can I change the height of a DropdownButton in flutter.
I have tried to use Padding and SizedBox but none is realy working.
SizedBox just increases the container size while the DropdownButton is clamped to top left and therefore is not centered anymore.
Padding is ignored or moves the content outside of the button.
I do not want to change the size of the dropdown overlay but the button itself.
build(BuildContext context) {
return ThemeData(
data: ThemeData(canvasColor: Colors.white),
child: DropdownButton(
items: _items.map((item) => DropdownMenuItem(child: Text(item), value: item)).toList(),
isExpanded: true,
selectedItemBuilder: (_) {
return _items.map<Widget>((String lang) {
return Center(
widthFactor: 1,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: Text(lang, style: TextStyle(color: Colors.black))
),
);
}).toList();
}
)
)
}
Wrap it in a Container, give a height, width as per your need and set isExpanded true in DropDownButton. Also change dropdownbutton text font size as per your need.
Container(
height: 50.0,
width: 200.0,
child: DropdownButton(
value: dropdownValue,
icon: Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
isExpanded: true,
style: TextStyle(color: Colors.deepPurple, fontSize: 20.0),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
items: <String>['One', 'Two', 'Free', 'Four']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
)
)
End product should look something like this,
Looks like the 'itemHeight' property for the DropdownButton class should do the trick. I tried it and it increased the height of my DropdownButton.
Here is some sample code I have from a previous project using the itemHeight:
DropdownButton<String>(
itemHeight: 100.0,
value: selectedCurrency,
items: dropdownItems,
onChanged: (value) {
setState(() {
selectedCurrency = value;
getData();
});
},
);
Note: Just make sure the value you provide isn't less than 48.0, since it will give an error.
Docs:
itemHeight property: https://api.flutter.dev/flutter/material/DropdownButton/itemHeight.html
Minimum itemHeight defined by 'kMinInteractiveDimension':
https://api.flutter.dev/flutter/material/kMinInteractiveDimension-constant.html
itemHeight: null,
You just need to leave the itemHeight with the null value.
It will make the height of the DropdownButton with the menu item's intrinsic height.
Use SizedBox Widget
SizedBox(
height: 30,
child:DropdownButton<String>(
value: selectedCurrency,
items: dropdownItems,
onChanged: (value) {},
))
The easiest of all methods is using DropDownButton2 which is built over DropDownButton
And just change the buttonHeight attribute
Not just buttonHeight , you can even change itemHeight , buttonwidth and many more customize
String? selectedValue;
List<String> items = [
'Item1',
'Item2',
'Item3',
'Item4',
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: DropdownButtonHideUnderline(
child: DropdownButton2(,
items: items
.map((item) =>
DropdownMenuItem<String>(
value: item,
child: Text(
item,
),
))
.toList(),
value: selectedValue,
onChanged: (value) {
setState(() {
});
},
buttonHeight: 40,
buttonWidth: 140,
itemHeight: 40,
),
),
),
);
}
checkout : DropDownButton2 for more examples.
Hope it helps !!
You need to use menuMaxHeight property of DropdownButton Widget.
child: DropdownButton(
menuMaxHeight: 500.0,
value: '1',
items: setTotalPages(),
onChanged: (String? newValue) {
setState(() {
dropdownvalue = newValue!;
});
},
)
Add this property menuMaxHeight: 200, to DropdownButton

How to set dynamic height for dropdown popup in flutter

I am new to flutter development. I am using the dropdown button of my application. When opening the drop-down menu, the text is getting cut in the popup dialog. Below I attached a screenshot with coding. Please guide me in fixing this issue.
DropdownButtonHideUnderline(
child: new DropdownButton(
isExpanded: true,
value: dropDownValue,
isDense: true,
//icon: Icon(Icons.keyboard_arrow_down, color: Colors.white,),
onChanged: (String newValue) {
setState(() {
dropDownValue = newValue;
state.didChange(newValue);
});
},
items: dropDownList.map((String value) {
return new DropdownMenuItem(
value: value,
child: new SizedBox(
width: MediaQuery.of(context).size.width / 1.4,
child: new Text(value,
softWrap: true,
style: TextStyle(color: Colors.white, fontSize: 18.0),),)
);
}).toList(),
),
),
);
Copying the DropdownMenuItem class as someone else suggested will not be enough as DropdownButton requires items to be of type List<DropdownMenuItem<T>>.
I have created the following widget which should help with your issue:
import 'package:flutter/material.dart';
/// Looks like a DropdownButton but has a few differences:
///
/// 1. Can be opened by a single tap even if the keyboard is showing (this might be a bug of the DropdownButton)
///
/// 2. The width of the overlay can be different than the width of the child
///
/// 3. The current selection is highlighted in the overlay
class CustomDropdown<T> extends PopupMenuButton<T> {
CustomDropdown({
Key key,
#required PopupMenuItemBuilder<T> itemBuilder,
#required T selectedValue,
PopupMenuItemSelected<T> onSelected,
PopupMenuCanceled onCanceled,
String tooltip,
double elevation = 8.0,
EdgeInsetsGeometry padding = const EdgeInsets.all(8.0),
Icon icon,
Offset offset = Offset.zero,
Widget child,
String placeholder = "Please select",
}) : super(
key: key,
itemBuilder: itemBuilder,
initialValue: selectedValue,
onSelected: onSelected,
onCanceled: onCanceled,
tooltip: tooltip,
elevation: elevation,
padding: padding,
icon: icon,
offset: offset,
child: child == null ? null : Stack(
children: <Widget>[
Builder(
builder: (BuildContext context) => Container(
height: 48,
alignment: AlignmentDirectional.centerStart,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
DefaultTextStyle(
style: selectedValue!= null ? Theme.of(context).textTheme.subhead
: Theme.of(context).textTheme.subhead.copyWith(color:
Theme.of(context).hintColor),
child: Expanded(child: selectedValue== null ? Text(placeholder) : child),
),
IconTheme(
data: IconThemeData(
color: Theme.of(context).brightness == Brightness.light
? Colors.grey.shade700 : Colors.white70,
),
child: const Icon(Icons.arrow_drop_down),
),
],
),
),
),
Positioned(
left: 0.0,
right: 0.0,
bottom: 8,
child: Container(
height: 1,
decoration: const BoxDecoration(
border: Border(bottom: BorderSide(color: Color(0xFFBDBDBD), width: 0.0)),
),
),
),
],
),
);
}
It actually extends PopupMenuButton as you can see, but I've made it look the same as the DropdownButton.
itemBuilder needs to return List<PopupMenuEntry<T>>, with each entry usually being a PopupMenuItem to which you can provide any child widget.
selectedValue is the currently selected value, which will be highlighted in the overlay. If it is null, a Text widget with the placeholder string is shown. If it is not null, the child widget is shown.
You should be able to disable the highlight by modifying this class to either call super() with an initialValue of null, or even better add a boolean to the constructor to control this from the outside.
The height of DropdownMenuItem is hardcoded to _kMenuItemHeight:
https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/dropdown.dart#L486
The only thing you can do is copy this entire file and adjust to your needs.