Flutter TextFormField text crops when width exceeds - flutter

I am using TextFormField for my flutter application search field.
When i type a text bigger that the width of textformfield, then entered text it cropped to half an not visible completely.
Please find my below code and attached image for more understanding of problem.
TextFormField(
focusNode: focusNode,
controller: textController,
decoration: InputDecoration(
border: InputBorder.none,
icon: Icon(
Icons.search,
),
hintText: AppStrings.searchCatHint,
hintStyle: TextStyle(
fontSize: 17,),
),
autovalidate: true,
autocorrect: false,
autofocus: true,
);
Screen for problem:
Similar problem i have seen in another question also, but no solution provided.
Similar issue link
Text display proper with #CarlosSR suggestion. But alignment issue as below.

I found a solution for the issue.
Problem description: On entering new text, old text should move to left without any problem.
Solution: I have specified a height for my TextFormField with Wrapping with Container. Code looks like below.
Container(
height:40,
child: TextFormFiled(...),
);
This worked for me. Thanks a lot for all your responses.

wrapping textformfield with container:
error will not occur:
Container(
color: Colors.black12,
width: 280,
height: 45,
child: TextFormField(
decoration: InputDecoration(
border: InputBorder.none,
icon: Icon(
Icons.search,
),
hintStyle: TextStyle(
fontSize: 17,),
),
autovalidate: true,
autocorrect: false,
autofocus: true,
),
),
error is with padding I guess if you are using:
Container(
color: Colors.black12,
width: 280,
height: 45,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
decoration: InputDecoration(
border: InputBorder.none,
icon: Icon(
Icons.search,
),
hintStyle: TextStyle(
fontSize: 17,),
),
autovalidate: true,
autocorrect: false,
autofocus: true,
),
),
),

This way you can only scroll the widget in horizontal axis, plus you add a padding to get your text in the position you want. In other, I recommend you to check for Align widget.
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
focusNode: focusNode,
controller: textController,
decoration: InputDecoration(
border: InputBorder.none,
icon: Icon(
Icons.search,
),
hintText: AppStrings.searchCatHint,
hintStyle: TextStyle(
fontSize: 17,),
),
autovalidate: true,
autocorrect: false,
autofocus: true,
),
),
),

I too happend to have the exact issue.The thing that i noticed that when i have a textfield in an container of some hardcoded height you might encounter this issue.Try removing the height of the container or just remove the textfields bottom padding.This will help.

The solution to this is using the CupertinoTextField widget. You can read about it here.

Related

TextField hint/input text not centered without prefixIcon after update to Flutter 1.12.13

I created TextFields with a custom height and a different background color. Here is the code snippet:
Container(
width: width,
height: 35,
decoration: BoxDecoration(
color: Constants.greyColor,
borderRadius: BorderRadius.all(Radius.circular(2)),
),
padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
textAlign: descriptor == null ? TextAlign.center : TextAlign.left,
decoration: InputDecoration(
hintText: placeholder,
hintStyle: Constants.textStyleTextInputHint,
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(horizontal: 0),
),
onChanged: (value) {
state.didChange(value);
},
obscureText: isPassword,
style: Constants.textStyleTextInput,
cursorColor: Constants.primaryColor,
),
),
It worked fine until I recently updated Flutter to version 1.12.13+hotfix.5. Now the hint text as well as the input text are not centered anymore. It seems as if the Container does not change the height of the TextField anymore. Like so:
If I add a prefixIcon the text and the icon will get perfectly centered. Like so:
Does anybody know how I can center the text without an Icon?
Thank you!
I think it's because you add a contentPadding property, even tho it's only horizontal. Have you tried removing it?
TextField(
textAlign: TextAlign.center
decoration: InputDecoration(
hintText: ...,
hintStyle: ...,
border: ...,
// contentPadding:
)
)

How do you make a `TextFormField` `prefixIcon` stay aligned at the top when `maxLines` is null?

I'm trying to make a TextFormField that has an unbounded input field, in the sense where if the user hits the enter key the box can be infinitely expanded. However, it seems that the prefixIcon attribute is wrapped in a Center, so whenever the user hits Enter the icon is realigned to the center of the text box, making for a particularly weird experience.
I've been trying to keep that icon from moving but nothing seems to work.
This is my form field:
TextFormField(
maxLines: null,
keyboardType: TextInputType.multiline,
style: theme.textTheme.body1,
decoration: InputDecoration(
prefixIcon: Icon(
Icons.description,
color: theme.iconTheme.color,
),
contentPadding: EdgeInsets.all(15.0),
hintText: 'Enter description'
),
)
you can use prefix: as instead of prefixIcon.
TextFormField(
maxLines: null,
keyboardType: TextInputType.multiline,
decoration: InputDecoration(
prefix: Icon(Icons.email),
hintText: 'Enter description'),
),
I solved by adding padding to the prefixIcon
prefixIcon: Padding(
padding: const EdgeInsets.only(bottom: 80),
child: Icon(
icon,
color: color,
),
),
Another hack is that you can also add some padding to the top to allow the ICON to move downwards
prefixIcon: Padding(
padding: const EdgeInsets.only(top:8),
child: Icon(
Icons.email,
color: Colors.blue,
),
),

How do I remove content padding from TextField?

I am new to flutter and I am creating login form, for that I have used TextField and added prefix icon but I am getting some extra spaces in between textfields (user id and pin) and before the prefix icon. I have also tried InputDecorationTheme but it didn't work.
Please let me know how can I remove or reduce the space.??
Below is my code:
TextField(
maxLength: 8,
keyboardType: TextInputType.number,
decoration: InputDecoration(
hintText: hint,
hintStyle: TextStyle(fontSize: 12.0),
prefixIcon: Icon(icon),
counterText: '',
),
)
Update (August 2022): still the same as of flutter 3.0.5
Update (April 2021): still work in flutter 2.0.4
As of flutter 1.17.5 (and still the same in 2.X) to completely remove or manipulate the padding manually, first you must set isDense: true and then you can adjust the contentPadding as you wanted or apply padding on the parent widget instead.
// using theme
ThemeData(
inputDecorationTheme: InputDecorationTheme(
isDense: true,// this will remove the default content padding
// now you can customize it here or add padding widget
contentPadding: EdgeInsets.symmetric(horizontal: 0, vertical: 0),
...
),
)
// per widget
TextField(
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.symmetric(horizontal: 0, vertical: 0),
...
),
)
As mentioned in the comment by Ataberk you can also use contentPadding: EdgeInsets.zero
TextField(
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.zero,
...
),
)
You can use contentPadding of InputDecoration.
Here is sample code
TextField(
maxLines: 8,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 5),
labelText: 'Description',
labelStyle: txtHintStyle,
)
)
I was able to easily achieve that by adding prefix constraints to the prefixIcon and wrapping the prefixIcon with padding like this
TextFormField(
enabled: true,
decoration: InputDecoration(
prefixIconConstraints:BoxConstraints(minWidth: 23, maxHeight: 20),
prefixIcon: Padding(
padding: const EdgeInsets.only(right: 20),
child: Icon(
Icons.email,
color: clockColor,
),
),
hintText:"Email Address"
hintStyle:TextStyle(color: hintColor, fontSize: 14),
),
),
heres the output,hope this helps
I come a bit late, but the only thing you have to do is to use negative padding :
TextField(
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: -5),
labelText: 'Description',
)
)
By applying minus padding by using
transform: Matrix4.translationValues(-10.0, 0.0, 0.0),
put above line inside the icon container
TextFormField(
keyboardType: TextInputType.number,
style: new TextStyle(color: Colors.white, fontSize: 17),
decoration: new InputDecoration(
prefixIcon: Container(
transform: Matrix4.translationValues(-10.0, 0.0, 0.0),
child: Icon(
Icons.vpn_key,
color: Colors.white,
),
),
labelText: "Enter Password",
labelStyle: new TextStyle(color: Colors.white)),
),
You can try this hack by reducing height of TextField
SizedBox(
height: 44, // set this
child: TextField(),
)
You can use:
TextField(
maxLines: 1,
decoration: InputDecoration(contentPadding: EdgeInsets.only(bottom: -10.0))
)
That prefixIcon has already contained the padding of 12.0 according to documentation.
So you don't need to provide extra padding.
See this below explanation & code which you can find in input_decorator.dart.
The prefix icon is constrained with a minimum size of 48px by 48px,
but can be expanded beyond that. Anything larger than 24px will
require additional padding to ensure it matches the material spec of
12px padding between the left edge of the input and leading edge of
the prefix icon. To pad the leading edge of the prefix icon:
prefixIcon: Padding(
padding: const EdgeInsetsDirectional.only(start: 12.0),
child: myIcon, // icon is 48px widget.
)
I hope it will help.
TextField(
decoration: InputDecoration(
isDense: true, //Set this to true
contentPadding: EdgeInsets.symmetric(vertical: 0),
hintText: 'Description',
)
)
Setting isDense: true will give you full control of setting the contentPadding. Make sure to set the EdgeInsets. as your need.
I have try many ways but only worked fine for me.
If you want to remove the left padding of Prefix icon, Give prefixIconConstraints:BoxConstraints(maxHeight: 20) to InpuDecoration .
TextField(
autocorrect: false,
textAlignVertical: TextAlignVertical.bottom,
onSubmitted: (value) {
getXHelper.textFieldSubmit(value, type);
},
decoration: InputDecoration(
isDense: true,
prefixIconConstraints:BoxConstraints(maxHeight: 20) ,
hintText: placeHolder,
prefixIcon: Padding(
padding: const EdgeInsets.only(top: 0, right: 5, bottom: 0),
child: Icon(
icon,
size: 20,
),
),
suffixIcon: type == TextFieldType.password ? passShowButton : null,
),
controller: controller,
cursorColor: Colors.black,
style:
TextStyle(color: Colors.black, fontFamily: AppFontFamily.fontFamily),
);
Please check the screen shot
replace prefixIcon-> prefix
TextFormField(
decoration: InputDecoration(
prefix:Icon(
Icons.perm_identity_outlined,
color: AppColors.primary,
),
labelText:'UserName'
),
)
You can set This value for TextFeild
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.symmetric(horizontal: 0, vertical: 0),
...
)
remove prefixIcon
Row(
children: [
//add icon
Icon(Icons.person,color: Colors.grey,),
Flexible(
child: TextFormField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'User Id',
contentPadding: EdgeInsets.all(0.0),//add content padding
isDense: true,//add isDense
),
),
),
],
),
//add some space between two row
SizedBox(height: 10,),
Row(
children: [
Icon(Icons.lock,color: Colors.grey,),
Flexible(
child: TextFormField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Pin',
contentPadding: EdgeInsets.all(0.0),
isDense: true,
),
),
),
],
),
I had to achieve something similar but could not find perfect solution. Came up with and work around using Stack widget.
Widget _username(context){
return SizedBox(
height: 35,
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Icon(
Icons.mail,
size: 20,
color: Theme.of(context).accentColor,
),
),
TextField(
style: TextStyle(
color: Colors.white
),
decoration: InputDecoration(
contentPadding: const EdgeInsets.symmetric(vertical: 11.0, horizontal: 33.0),
hasFloatingPlaceholder: false,
labelText: 'Username',
labelStyle: TextStyle(
color: Colors.white
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).accentColor,
)
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).accentColor,
),
),
),
),
]
),
);
}
SizedBox is used to control the vertical padding. For horizontal padding, Icon and TextField are stacked. This results overlapped TextField's label above Icon so contentPadding property is used to move the label to the right. With this I achieved following look.

How to change TextField's height and width?

How to customise TextField's width and height?
To adjust the width, you could wrap your TextField with a SizedBox widget, like so:
const SizedBox(
width: 100.0,
child: TextField(),
)
I'm not really sure what you're after when it comes to the height of the TextField but you could definitely have a look at the TextStyle widget, with which you can manipulate the fontSize and/or height
const SizedBox(
width: 100.0,
child: TextField(
style: TextStyle(fontSize: 40.0, height: 2.0, color: Colors.black),
),
)
Bear in mind that the height in the TextStyle is a multiplier of the font size, as per comments on the property itself:
The height of this text span, as a multiple of the font size.
When [height] is null or omitted, the line height will be determined
by the font's metrics directly, which may differ from the fontSize.
When [height] is non-null, the line height of the span of text will be a
multiple of [fontSize] and be exactly fontSize * height logical pixels
tall.
Last but not least, you might want to have a look at the decoration property of you TextField, which gives you a lot of possibilities
EDIT: How to change the inner padding/margin of the TextField
You could play around with the InputDecoration and the decoration property of the TextField. For instance, you could do something like this:
const TextField(
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 40.0),
),
)
I think you want to change the inner padding/margin of the TextField.
You can do that by adding isDense: true and contentPadding: EdgeInsets.all(8) properties as follow:
Container(
padding: EdgeInsets.all(12),
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Default TextField',
),
),
SizedBox(height: 16,),
TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Densed TextField',
isDense: true, // Added this
),
),
SizedBox(height: 16,),
TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Even Densed TextFiled',
isDense: true, // Added this
contentPadding: EdgeInsets.all(8), // Added this
),
)
],
),
)
It will be displayed as:
Screenshot:
You can do it in many ways:
Using maxLines + expands:
SizedBox(
width: 240, // <-- TextField width
height: 120, // <-- TextField height
child: TextField(
maxLines: null,
expands: true,
keyboardType: TextInputType.multiline,
decoration: InputDecoration(filled: true, hintText: 'Enter a message'),
),
)
Using just maxLines:
Widget _buildTextField() {
final maxLines = 5;
return Container(
margin: EdgeInsets.all(12),
height: maxLines * 24.0,
child: TextField(
maxLines: maxLines,
keyboardType: TextInputType.multiline,
decoration: InputDecoration(filled: true, hintText: 'Enter a message'),
),
);
}
This answer works, but it will have conflicts when the input field is in error state, for a better approach and a better control you can use this.
InputDecoration(
isCollapsed: true,
contentPadding: EdgeInsets.all(9),
)
If you want to increase the height of TextFormField dynamically while typing the text in it. Set maxLines to null. Like
TextFormField(
onSaved: (newText) {
enteredTextEmail = newText;
},
obscureText: false,
keyboardType: TextInputType.emailAddress,
validator: validateName,
maxLines: null,
// style: style,
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(5.0, 10.0, 5.0, 10.0),
hintText: "Enter Question",
labelText: "Enter Question",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0))),
),
Wrap TextField in SizedBox for the width
SizedBox(
height: 40,
width: 150,
child: TextField(),
)
You can try the margin property in the Container. Wrap the TextField inside a Container and adjust the margin property.
new Container(
margin: const EdgeInsets.only(right: 10, left: 10),
child: new TextField(
decoration: new InputDecoration(
hintText: 'username',
icon: new Icon(Icons.person)),
)
),
If you use "suffixIcon" to collapse the height of the TextField add:
suffixIconConstraints
TextField(
style: TextStyle(fontSize: r * 1.8, color: Colors.black87),
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.symmetric(vertical: r * 1.6, horizontal: r * 1.6),
suffixIcon: Icon(Icons.search, color: Colors.black54),
suffixIconConstraints: BoxConstraints(minWidth: 32, minHeight: 32),
),
)
simply wrap the TextField() in SizedBox() and give the height of the sized box
use contentPadding, it will reduce the textbox or dropdown list height
InputDecorator(
decoration: InputDecoration(
errorStyle: TextStyle(
color: Colors.redAccent, fontSize: 16.0),
hintText: 'Please select expense',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(1.0),
),
contentPadding: EdgeInsets.all(8)),//Add this edge option
child: DropdownButton(
isExpanded: true,
isDense: true,
itemHeight: 50.0,
hint: Text(
'Please choose a location'), // Not necessary for Option 1
value: _selectedLocation,
onChanged: (newValue) {
setState(() {
_selectedLocation = newValue;
});
},
items: citys.map((location) {
return DropdownMenuItem(
child: new Text(location.name),
value: location.id,
);
}).toList(),
),
),
Set minLines: null, maxLines: null and expands:true to let the TextField fill the height of its parent widget:
Container(
child: TextField(
minLines: null,
maxLines: null,
expands: true
)
)
Refere to these docs for the same:https://api.flutter.dev/flutter/material/TextField/expands.html
And for width, you can do this:
Container(
width: 100,
child: TextField(
)
)
to let the TextField fill its parent widget's width(100 pixels in this case)
Adjust Height using contentPadding instead of SizeBox or Container
Container(
width: width * 0.85,
child: TextFormField(
textInputAction: TextInputAction.next,
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
contentPadding: const EdgeInsets.symmetric(vertical: 10), //Imp Line
isDense: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
borderSide: const BorderSide(
width: 0.5,
color: Constants.secondaryColourLight,
)),
),),)
80k ka code hein 80k ka
Finally, I got my solution using this trick.
Provide Height and width of sizedbox and set expand the property to true. Also, set maxLines to null and minLines to null.
SizedBox(
height: SizeConfig.screenWidth * 0.1377,
child: TextFormField(
validator: validator,
enabled: isEnabled,
expands: true,
maxLines: null,
minLines: null,
),
);
TextField( minLines: 1, maxLines: 5, maxLengthEnforced: true)
int numLines = 0;
Container(
height: numLines < 7 ? 148 * WidgetsConstant.height: numLines * WidgetsConstant.height * 24,
child: TextFormField(
controller: _bodyText,
maxLines: numLines < 7 ? 148 : numLines,
keyboardType: TextInputType.multiline,
textInputAction: TextInputAction.newline,
onChanged: (String value) {
setState(() {
numLines = '\n'.allMatches(value).length + 1;
});
},
),
),
The perfect way to get rid of padding is to use InputDecoration.collapsed.
It wraps the GestureDetector with a Container and decorates the Container with as much Padding, Border, and Decoration as needed.
GestureDetector(
onTap: () => _focusNode.requestFocus(),
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.circular(4),
),
child: TextField(
focusNode: _focusNode,
decoration: const InputDecoration.collapsed(
hintText: 'Search...',
border: OutlineInputBorder(
borderSide: BorderSide(
width: 0,
style: BorderStyle.none,
),
),
),
),
),
);
To display an icon, change the Container child to Row, and use Icon and a TextField wrapped with Expanded.
To increase the height of TextField Widget just make use of the maxLines: properties that comes with the widget. For Example:
TextField(
maxLines: 5
) // it will increase the height and width of the Textfield.
You can simply wrap Text field widget in padding widget.....
Like this,
Padding(
padding: EdgeInsets.only(left: 5.0, right: 5.0),
child: TextField(
cursorColor: Colors.blue,
decoration: InputDecoration(
labelText: 'Email',
hintText: 'xyz#gmail.com',
//labelStyle: textStyle,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
borderSide: BorderSide(width: 2, color: Colors.blue,)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(width: 2, color: Colors.green)),
)
),
),
You can change max
minLines: 4,
maxLines: 6,
Provide a maxLines and add a BoxConstraints with width and height in InputDecoration.
TextField(
maxLines: 10,
decoration: InputDecoration(
border: OutlineInputBorder(borderRadius: BorderRadius.circular(10)),
constraints: BoxConstraints.tightFor(width: 300, height: 100),
),
);
TextField(
decoration: InputDecoration(
border: OutlineInputBorder(borderRadius: BorderRadius.circular(10)),
constraints: BoxConstraints(maxHeight:48,maxWidth: 327,),
),
);

How to vertically center differently-sized hintText in TextField?

I have a TextField like this, where the input text and the hint text are sized differently.
TextField(
style: Theme.of(context).textTheme.subhead.copyWith(
fontSize: 70.0,
),
decoration: InputDecoration(
hintText: 'Enter a number',
hideDivider: true,
hintStyle: TextStyle(
color: Colors.grey[500],
fontSize: 25.0,
),
),
);
While the user input text is centered in my parent container, the hintText is not (top has more space than the bottom). Is there a way to vertically center the hint text as well?
The reason the hint text is not the same size as the input text is that it takes up more space than the green Container has, so it looks like Enter a nu..., which isn't very user friendly. (So alternatively, is there a way to have a newline in the hintText?)
I see this is over 2 years old but in case others run into this problem:
InputDecoration has the property contentPadding.
TextField(
decoration: InputDecoration(
hintText: 'Hint Text',
contentPadding: EdgeInsets.all(10.0),
),
);
Add textAlignVertical: TextAlignVertical.center, in your TextField.
Note: make sure you are not modifying it with other Containers or anything else & if you do then check those widgets as well.
TextField(
textAlignVertical: TextAlignVertical.center,
),
new TextField(
decoration: new InputDecoration(
hintText: 'your hint',
),
textAlign: TextAlign.center,
)
textAlign: TextAlign.center will make your hint appear in the center.
Below is the solution for your problem:
Container(
color: Colors.red,
width: 1000,
height: 500,
alignment: Alignment.center,
child: TextFormField(
keyboardType: TextInputType.emailAddress,
autofocus: false,
style: new TextStyle(fontSize: 20),
decoration: InputDecoration(
hintText: 'Email', hintStyle: TextStyle(color: Color(0xff777777))),
),
)