How to change height of country_picker? - flutter

I am using country_picker for drop-down-menu.
And I need to reduce height of this menu. How can I do this?
And how to get border to showCountryPicker?
This is what I want
And this what I get
I tried to add bottomSheetHeight, but it hides my bottom buttons.
And without bottomSheetHeigh the drop-down-menu is in full screen mode
This is my code:
Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 12, right: 12),
child: TextFormField(
controller: _country,
readOnly: true,
onTap: () {
showCountryPicker(
context: context,
showWorldWide: false,
showPhoneCode: false,
showSearch: false,
countryListTheme: CountryListThemeData(
backgroundColor: AppColors.backgroundColor,
borderRadius: BorderRadius.circular(8),
bottomSheetHeight: 380,
flagSize: 0,
textStyle: TextStyle(
color: AppColors.grayA0A0A0,
fontSize: 18,
height: 2.0
)
),
onSelect: (Country country) {
log(country.toString());
}
);
},
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
borderSide: const BorderSide(width: 0)),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(width: 1, color: AppColors.darkGray),
borderRadius: BorderRadius.circular(10)),
hintText: "Choose a country",
hintStyle: const TextStyle(
color: AppColors.grayA0A0A0, fontWeight: FontWeight.w500),
filled: true,
fillColor: AppColors.lightDark,
contentPadding:
const EdgeInsets.only(left: 8, bottom: 20, top: 20),
prefixIcon: InkWell(
child: SvgPicture.asset(
"assets/icons/Country.svg",
color: AppColors.grayA0A0A0,
height: 14,
width: 18,
fit: BoxFit.scaleDown,
),
),
suffixIcon: InkWell(
child: SvgPicture.asset(
"assets/icons/arrow_down.svg",
color: AppColors.grayA0A0A0,
height: 14,
width: 18,
fit: BoxFit.scaleDown,
),
)
),
),
),
),

Row(
children: <Widget>[
Expanded(
flex: 1,
//SizedBox(height: 20.0),
child: CountryPicker(
dense: true,
showFlag: false, //displays flag, true by default
showDialingCode:
true, //displays dialing code, false by default
showName: true, //displays country name, true by default
showCurrency: false, //eg. 'British pound'
showCurrencyISO: false,
onChanged: (Country country) {
setState(() => _selected = country);
print(country.dialingCode);
countryCode = country.dialingCode;
},
selectedCountry: _selected,
),
),
Expanded(
flex: 3,
//SizedBox(height: 20.0),
child: TextFormField(
decoration: InputDecoration(
labelText: 'Mobile no.',
border: OutlineInputBorder(),
),
validator: (val) => val.length != 10
? 'Enter a mobile number of 10 digits'
: null,
onChanged: (val) {
setState(() => phone = val);
phoneno = phone;
},
),
),
],
),

Related

How to reduce the height of the DropDownButtonFormField so that the text inside it does not go out of the middle in flutter?

When I set a height for my container that is the parent of DropDownButtonFormField, I have no problem when the height is 55, but when the height is less (42) than a certain limit, the text inside it looks like this.
As it is clear in the picture, cat is no longer in the middle of the container.
this is my code:
Container(
alignment: Alignment.center,
width: double.infinity,
height: 40,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: const Color(0xFF616161),
width: 0.65,
),
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: EdgeInsets.fromLTRB(0, 0, 10, 0),
child: DropdownButtonFormField(
enableFeedback: true,
menuMaxHeight: 200,
icon: Icon(Icons.keyboard_arrow_down_rounded),
iconSize: 21,
alignment: Alignment.center,
// decoration: InputDecoration.collapsed(hintText: ''),
decoration: InputDecoration(
border: InputBorder.none,
prefixIcon: Icon(Icons.location_on_rounded),
),
dropdownColor: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(8)),
elevation: 2,
// isExpanded: true,
value: cityValue,
onChanged: (String? newValue) {
setState(() {
cityValue = newValue!;
});
},
items: <String>['Tehran', 'Cat', 'Tiger', 'Lion']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style:
TextStyle(fontSize: 15, color: Color(0xff707070)),
),
);
}).toList(),
),
),
),
The icon is in the middle but not the text.
I used Offset, but then the icon gets messed up.
The default Icon size 24, so you need minimum height 48 to view properly. It would be better not to force it have certain height.You can remove height 40 for better UX.
Now let say you like to have fixed hight, for this case, you need to maintain padding for yourself.
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(top: 6), //this one
prefixIcon: Icon(Icons.location_on_rounded),
),
Container(
alignment: Alignment.center,
width: double.infinity,
height: 40,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: const Color(0xFF616161),
width: 0.65,
),
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
child: DropdownButtonFormField(
enableFeedback: true,
menuMaxHeight: 200,
icon: Icon(Icons.keyboard_arrow_down_rounded),
iconSize: 20,
alignment: Alignment.center,
// decoration: InputDecoration.collapsed(hintText: ''),
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.only(top: 6), //this one
prefixIcon: Icon(Icons.location_on_rounded),
),
dropdownColor: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(8)),
elevation: 2,
onChanged: (String? newValue) {},
items: <String>['Tehran', 'Cat', 'Tiger', 'Lion']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style:
TextStyle(fontSize: 15, color: Color(0xff707070)),
),
);
}).toList(),
),
),
),
A quick solution is adding a contentPadding to the InputDecoration.
contentPadding: EdgeInsets.symmetric(vertical: 7),
Try below code using InputDecoration
DropdownButtonFormField(
decoration: const InputDecoration(
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(width: 1, color: Colors.grey),
),
contentPadding: EdgeInsets.symmetric(
horizontal: 10.0,
vertical: 3.0,
),
border: OutlineInputBorder(),
prefixIcon: Icon(
Icons.location_on_rounded,
color: Colors.grey,
),
),
dropdownColor: Colors.white,
borderRadius: const BorderRadius.all(
Radius.circular(8),
),
icon: const Icon(Icons.keyboard_arrow_down_rounded),
onChanged: (value) => {
cityValue = value!,
},
items: <String>['Tehran', 'Cat', 'Tiger', 'Lion']
.map(
(e) => DropdownMenuItem(
value: e,
child: Text(e),
),
)
.toList(),
),
Your Result Screen->

Flutter Validation Error Message Position

I'm trying to get the image in the picture. However, the problem is: I can't show the error message below the line. When I show the error message, it looks like this and gives an error.
What properties can I use to achieve this to get the image in the design? I would be glad if you help
Can we change the position of the error message in Flutter? Can you help me with this?
DESIGN;
My Code:
Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Telefon Numarası',
style: TextStyle(color: Colors.grey),
),
Container(
decoration: const BoxDecoration(
border: Border(bottom: BorderSide(width: 1, color: Colors.grey))
),
child: Stack(
children: [
Positioned(
bottom: 10,
top: 10,
left: 0,
child: Container(
height: 30,
width: 80,
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.circular(5),
),
child: Row(
children: const [
Spacer(),
Icon(CupertinoIcons.chevron_down, size: 16,),
SizedBox(width: 5,),
],
),
),
),
SizedBox(
height: 50,
child: InternationalPhoneNumberInput(
hintText: 'Telefon Numarası',
onInputChanged: (PhoneNumber number) {
print(number.phoneNumber);
},
onInputValidated: (bool value) {
print(value);
},
ignoreBlank: false,
autoValidateMode: AutovalidateMode.disabled,
selectorTextStyle: const TextStyle(
color: Colors.black,
),
selectorConfig: const SelectorConfig(
selectorType: PhoneInputSelectorType.BOTTOM_SHEET,
setSelectorButtonAsPrefixIcon: false,
leadingPadding: 10,
showFlags: false,
trailingSpace: true,
),
initialValue: PhoneNumber(isoCode: 'TR'),
textFieldController: TextEditingController(),
formatInput: false,
keyboardType: TextInputType.numberWithOptions(
signed: true, decimal: true),
inputDecoration: const InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent)
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent)
),
floatingLabelAlignment: FloatingLabelAlignment.start,
// labelText: 'Telefon Numarası',
),
textStyle: const TextStyle(color: Colors.black),
onSaved: (PhoneNumber number) {
print('On Saved: $number');
},
),
),
],
),
),
],
),
),
MY OUTPUT;
here the error message should come under the line at the bottom

Flutter Phone Number TextField With Country Code

I'm trying to make the phone number field in the design. I'm using the intl_phone_number_input package for this but I couldn't do it like in my design.
I would be glad if you can help with this.
My design:
My Output:
My code:
InternationalPhoneNumberInput(
hintText: 'Telefon Numarası',
onInputChanged: (PhoneNumber number) {
print(number.phoneNumber);
},
onInputValidated: (bool value) {
print(value);
},
ignoreBlank: false,
autoValidateMode: AutovalidateMode.disabled,
selectorTextStyle: TextStyle(
color: Colors.black,
backgroundColor: Colors.grey,
),
selectorConfig: const SelectorConfig(
selectorType: PhoneInputSelectorType.DROPDOWN,
setSelectorButtonAsPrefixIcon: true,
leadingPadding: 0,
showFlags: false,
trailingSpace: false),
initialValue: PhoneNumber(isoCode: 'TR'),
textFieldController: TextEditingController(),
formatInput: false,
keyboardType: TextInputType.numberWithOptions(
signed: true, decimal: true),
inputBorder: UnderlineInputBorder(),
inputDecoration: InputDecoration(
floatingLabelAlignment: FloatingLabelAlignment.start,
labelText: 'Telefon Numarası',
),
textStyle: AppTextStyle().getSfProDisplayMedium(Colors.black),
onSaved: (PhoneNumber number) {
print('On Saved: $number');
},
),
I think we can use a combination of two types widget, I try use Stack
And this is my UI:
My code:
Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Telefon Numarası',
style: TextStyle(color: Colors.grey),
),
Container(
decoration: const BoxDecoration(
border: Border(bottom: BorderSide(width: 1, color: Colors.grey))
),
child: Stack(
children: [
Positioned(
bottom: 10,
top: 10,
left: 0,
child: Container(
height: 30,
width: 80,
decoration: BoxDecoration(
color: Colors.grey.shade300,
borderRadius: BorderRadius.circular(5),
),
child: Row(
children: const [
Spacer(),
Icon(CupertinoIcons.chevron_down, size: 16,),
SizedBox(width: 5,),
],
),
),
),
SizedBox(
height: 50,
child: InternationalPhoneNumberInput(
hintText: 'Telefon Numarası',
onInputChanged: (PhoneNumber number) {
print(number.phoneNumber);
},
onInputValidated: (bool value) {
print(value);
},
ignoreBlank: false,
autoValidateMode: AutovalidateMode.disabled,
selectorTextStyle: const TextStyle(
color: Colors.black,
),
selectorConfig: const SelectorConfig(
selectorType: PhoneInputSelectorType.BOTTOM_SHEET,
setSelectorButtonAsPrefixIcon: false,
leadingPadding: 10,
showFlags: false,
trailingSpace: true,
),
initialValue: PhoneNumber(isoCode: 'TR'),
textFieldController: TextEditingController(),
formatInput: false,
keyboardType: TextInputType.numberWithOptions(
signed: true, decimal: true),
inputDecoration: const InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent)
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent)
),
floatingLabelAlignment: FloatingLabelAlignment.start,
// labelText: 'Telefon Numarası',
),
textStyle: const TextStyle(color: Colors.black),
onSaved: (PhoneNumber number) {
print('On Saved: $number');
},
),
),
],
),
),
],
),
),

Drop down inside text field flutter

This is what I have currently:
My design / what I want it to be:
This is my code and this sized box is a part of a column which is a part of a form:
SizedBox(
height: 80.0,
child: Stack(alignment: Alignment.centerRight, children: [
TextFormField(
controller: null,
style: const TextStyle(color: Colors.white),
maxLength: 2,
decoration: InputDecoration(
fillColor: const Color(0xff353251),
filled: true,
hintText: 'ex. 5 hours',
contentPadding: const EdgeInsets.all(20.0),
hintStyle: const TextStyle(color: Colors.white24),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15.0)))),
DropdownButton(
value: goalValue,
dropdownColor: const Color(0xff403A4F),
style: const TextStyle(color: Colors.white),
onChanged: (String? value) {
setState(() {
goalValue = value!;
});
},
items: <String>['Per Week', 'Per Day', 'Per Month']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList()),
]),
),
Thanks in advance!
Instead of Stack, I am using Container for outer decoration and Row for placing two widgets. There are many changes occur during styling the property and used random color, play with styling.
Now The result is
Container(
alignment: Alignment.center,
padding: const EdgeInsets.only(left: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: Color(0xff353251),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Flexible(
flex: 2,
child: TextField(
controller: null,
style: TextStyle(color: Colors.white),
maxLength: 2,
buildCounter: null,
decoration: InputDecoration(
fillColor: Color(0xff353251),
filled: true,
counterText: "",
hintText: 'ex. 5 hours',
contentPadding: EdgeInsets.only(right: 4),
hintStyle: TextStyle(color: Colors.white24),
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
),
),
),
Flexible(
flex: 1,
child: Container(
padding: EdgeInsets.only(right: 16, left: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
color: Colors.purpleAccent,
),
child: Theme(
data: Theme.of(context).copyWith(
canvasColor: Colors.purpleAccent,
),
child: DropdownButton(
borderRadius: BorderRadius.circular(15.0),
underline: const SizedBox(),
icon: const SizedBox(),
value: goalValue,
style: const TextStyle(color: Colors.white),
hint: const Text(
"select",
style: TextStyle(color: Colors.white),
),
onChanged: (String? value) {
setState(() {
goalValue = value!;
});
},
items: <String>['Per Week', 'Per Day', 'Per Month']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList()),
),
),
),
],
),
),

How to add divider to dropdown list?

I have the following dropdown:
DropdownButtonFormField(
isExpanded: true,
isDense: true,
value: dropdownValue,
icon: SvgPicture.asset(
AppImages.ic_expand_dropdown,
),
iconDisabledColor: AppColors.colorDarkGray,
iconEnabledColor: AppColors.colorDarkGray,
focusNode: widget.focusNode,
validator: widget.validator,
decoration: InputDecoration(
label: widget.widgetLabel,
labelStyle:
widget.labelStyle ?? AppTextStyles.transparentBlueDark16(),
labelText: widget.isLabelRes
? AppLocales.getTextOrNull(widget.label)
: widget.label,
fillColor: Colors.white,
filled: true,
hintText: widget.pickerPlaceholder,
hintStyle: widget.hintStyle ?? AppTextStyles.alto16(),
alignLabelWithHint: true,
errorText: widget.isErrorRes
? AppLocales.getTextOrNull(widget.error)
: widget.error,
contentPadding: const EdgeInsets.symmetric(
horizontal: 0,
vertical: 0,
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
width: 1,
color:
widget.enabledBorderColor ?? AppColors.colorInputBorder,
),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
width: 2,
color: widget.focusedBorderColor ?? AppColors.colorAccent,
),
),
errorBorder: UnderlineInputBorder(
borderSide: BorderSide(
width: 2,
color: AppColors.colorError,
),
),
border: UnderlineInputBorder(
borderSide: BorderSide(
width: 1,
color: widget.borderColor ?? AppColors.colorInputBorder,
),
),
),
style: AppTextStyles.grayDark16(
fontWeight: AppFontWeight.medium,
),
onChanged: (String? newValue) {
dropdownValue = newValue;
widget.onChanged(dropdownValue!);
},
items: widget.pickerList.map<DropdownMenuItem<String>>((value) {
return DropdownMenuItem<String>(
value: value,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10),
),
),
child: Text(
value,
style: AppTextStyles.grayDark16(
fontWeight: AppFontWeight.medium,
),
),
),
Visibility(
child: Divider(
color: AppColors.colorEden10,
height: 2.0,
indent: 10.0,
endIndent: 10.0,
),
visible: widget.pickerList.last != value,
),
],
),
);
}).toList(),
),
I need to display the dividers between items. As I didn't find any option to add it as in List, I added the divider by creating a Column that contains Text and Divider which is shown in some cases. But the problem is that when I select the item divider is also displayed in dropdown as a result and I don't see any option to hide it here. Is there any way to add a divider without displaying it after selecting item?
To avoid selected Item Divider, we need to use selectedItemBuilder:. By default, it uses items layout.
You can use on DropdownButtonFormField like
selectedItemBuilder: (context) => widget.pickerList
.map(
(text) => Text(text),
)
.toList(),
You can set your own logic to create the UI.
And the simplified State-snippet is
late List<DropdownMenuItem<String>> menuItems = [];
#override
void initState() {
super.initState();
dropdownValue = widget.pickerList.first;
for (int i = 0; i < widget.pickerList.length; i++) {
//* on 1st index there will be no divider
i == 0
? menuItems.add(
DropdownMenuItem<String>(
child: Text(
widget.pickerList[i],
),
value: widget.pickerList[i],
),
)
: menuItems.add(
DropdownMenuItem<String>(
child: Container(
width: double.maxFinite,
alignment: Alignment.centerLeft,
padding: const EdgeInsets.only(
top: 6, // adjust the way you like
),
decoration: const BoxDecoration(
border: Border(
top: BorderSide(
color: Colors.grey,
width: 2,
),
),
),
child: Text(
widget.pickerList[i],
),
),
value: widget.pickerList[i],
),
);
}
}
#override
Widget build(BuildContext context) {
return DropdownButtonFormField<String>(
isExpanded: true,
isDense: true,
value: dropdownValue,
onChanged: (String? newValue) {
// dropdownValue = newValue;
// widget.onChanged(dropdownValue!);
},
items: menuItems,
selectedItemBuilder: (context) => widget.pickerList
.map(
(text) => Text(text),
)
.toList(),
);
}