How to reduce padding on prefixIcon on TextField? - flutter

I can't figure out how to get past the 48px Material library default. I did a quick scan through the SDK and couldn't find anything. I know it's something to do with the prefixIcon parameter itself because it will always be 48px or whatever it is no matter what is placed inside.
I have a custom SDK so if anyone knows where it is I'd like to reduce it because it always just gets in the way.
// : Searchbar Decoration
static InputDecoration searchbarDecoration = InputDecoration(
prefixIcon: Icon(
Icons.search,
color: DocumentColours.colour10,
),
contentPadding: EdgeInsets.symmetric(
vertical: 0.0,
horizontal: 0.0,
),
fillColor: DocumentColours.colour8,
filled: true,
labelText: 'Search',
labelStyle: FontStyles.searchbarLabel,
hasFloatingPlaceholder: false,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
borderSide: BorderSide(width: 0.0, style: BorderStyle.none),
),
);

NOTE: To solve this, use the prefixIconConstraints property of the InputDecoration as of SDK version 1.17.0
Below is what the documentation says (1.17.0) input_decorater.dart:
BoxConstraints can be used to modify the surrounding of the prefixIcon.
This property is particularly useful for getting the decoration's height less than 48px. This can be achieved by setting [isDense] to true and
setting the constraints' minimum height and width to a value lower than 48px.
Check the code below: It works perfectly:
TextField(
decoration: InputDecoration(
// choose any icon of your choice here
prefixIcon: Icon(Icons.person),
// set the prefix icon constraints
prefixIconConstraints: BoxConstraints(
minWidth: 25,
minHeight: 25,
),
),
),
I hope this helps.

My way is to custom my own textfield component using Row > Icon + TextField, just forget there is a prefixIcon in TextField.
like:
Container(
width: 200.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(3.0),
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(
left: 13.0,
right: 6.0,
),
child: Icon(
Icons.search,
size: 16.0,
),
),
TextField(
// ...
),
],
),
),

Related

How to align suffixIcon to top of multi line TextField?

code:
TextField(
maxLines:null,
decoration: InputDecoration(
suffixIcon: Icon(Icons.delete),
),
)
Everytime a new line is inserted, the icon centers itself.
I found a work-around. Just use suffix property of TextField instead of suffixIcon
code:
TextField(
maxLines:null,
decoration: InputDecoration(
suffix: Icon(Icons.delete),
),
)
output:
Note: This solution may affect the design of your TextField and the Icon is not visible when TextField is not focused or when it has no data
Here is what I achieved using Padding around Icon:
Container(
height: 100,
child: TextField(
expands: true,
maxLines: null,
decoration: InputDecoration(
suffixIcon: Padding(
padding:
const EdgeInsets.only(left: 0, top: 0, right: 0, bottom: 100),
child: Icon(Icons.add),
)),
),
)

Flutter TextField height not increasing

I am trying to increase my text field height but it's not increasing I already try wrapping with the container and increase the height of the container but it just increases the background height not text field height.
Also maxLines is working but needs to increase by height so I can add some shadows in container
import 'package:flutter/material.dart';
import 'package:curved_navigation_bar/curved_navigation_bar.dart';
import 'package:mytravel/screens/loginPage.dart';
import 'package:mytravel/screens/guidePlacePage.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:async';
import 'dart:io';
class addPostPage extends StatefulWidget {
#override
_addPostPageState createState() => _addPostPageState();
}
class _addPostPageState extends State<addPostPage> {
File _image;
Future getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_image = image;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFEDF0F6),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 75, right: 10, left: 10),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(25.0),
),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: Column(
children: <Widget>[
InkWell(
onTap: () {
getImage();
},
child: Container(
margin: EdgeInsets.all(10.0),
width: double.infinity,
height: 400.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
boxShadow: [
BoxShadow(
color: Colors.black45,
offset: Offset(0, 5),
blurRadius: 8.0,
),
],
image: DecorationImage(
image: _image == null
? AssetImage("assets/images/post0.jpg")
: Image.file(_image),
fit: BoxFit.fitWidth,
),
),
),
),
],
),
),
Container(
height: 200, //here you can see try to increase height
padding: EdgeInsets.only(right: 15, left: 15),
child: TextField(
style: TextStyle(
fontSize: 20,
),
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.green),
borderRadius: BorderRadius.all(Radius.circular(20)),
),
fillColor: Colors.white,
filled: true,
border: InputBorder.none,
hintText: 'Your short story of image',
),
),
)
],
),
),
),
],
),
),
);
}
}
the contentPadding controls the height of the TextField if you want to increase the height of your text then you would alter the height property in TextStyle
TextField(
style: TextStyle(height: 4 // controls the height on main text
),
controller: _controller,
decoration: InputDecoration(
contentPadding: // Text Field height
EdgeInsets.symmetric(
vertical: 25.0, horizontal: 10.0),
hintStyle: TextStyle(
height: 4, //Controls the height of the hint text
),
errorStyle:
TextStyle(), // Controls style of error message
counterStyle:
TextStyle(), //Controls style of the counter if you have one
helperStyle:
TextStyle(), //Controls style of the helper message
labelStyle:
TextStyle(), //Controls style of the label message
prefixStyle:
TextStyle() //Controls the style of the prefix
),
),
let me know if this works
First Option: (Make sure to match the height)
TextField(
style: TextStyle(
height: 1.5, // change this to reflect the effect
fontSize: 20.0
),
hintStyle: TextStyle(
height: 1.5, //Controls the height of the hint text
),
)
Second Option:
TextField(
decoration: const InputDecoration(
contentPadding: const EdgeInsets.symmetric(vertical: 40.0),
)
)
Plus wcyankees424 answer provides more options, even for success,error etc. hints.
Read this page please:
https://api.flutter.dev/flutter/painting/TextStyle/height.html
As it is described you need add a height property for text. So you need add this line after font size:
height:2.0;
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.

How to make the TextField expands in flutterwhen the user types in it?

I am setting a text field which will expands when Enter is pressed in the keyboard
when i tried to set null in max lines it does not show the text inside text field
i even set that expands = true
i used media query size in somewhere which is size.height in the code
i wrapped the text field within the Flexible widget
and add some padding then the total flexible widget is wrapped within a Row
and finally the row is wrapped within a Container
so this code is not working help me to fix this
Container(
height: size.height * .059,
width: double.infinity,
child: new Row(
children: <Widget>[
new Flexible(
child: Padding(
padding: EdgeInsets.only(right: size.width * 0.007),
child: new TextField(
controller: _textFieldController,
textInputAction: TextInputAction.newline,
keyboardType: TextInputType.multiline,
maxLines: null,
expands: true,
style: TextStyle(color: Colors.black),
cursorColor: Colors.blue,
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
borderSide: BorderSide(color: Color(0xff8e9291))),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
borderSide: BorderSide(color: Color(0xff8e9291))),
prefixIcon: Icon(
Icons.message,
color: Color(0xff8e9291),
),
hintText: "Type a message",
hintStyle: TextStyle(
color: Color(0xff8e9291),
),
),
),
),
),
FloatingActionButton(
backgroundColor: Colors.blue[400],
onPressed: () {
},
tooltip: 'Send',
child: RotationTransition(
turns: AlwaysStoppedAnimation(-35 / 360),
child: Icon(
Icons.send,
size: 20,
)),
),
],
),
),
this is the Text field i'm using..
You could remove the height of the Container since that will make a fixed height, and remove the expands of the TextField since that is to make it to fill its parent height.
You could set MaxLine property to null 'maxLines: null`
this will enable textField to Expand Vertical

Flutter TextField clear button position wrong

I want to have a clear button for my textfield. I found an example of how to add it using decoration, but its position is completely off. How can I adjust the position of the icon?
Also, I cannot get the input text to be centered in the input field. I didn't find anything how to vertically center the text in the input box.
Thanks!
...
TextEditingController _textFieldController = TextEditingController();
...
Widget searchField(BuildContext context) {
return Container(
width: 200,
height: 30,
color: Colors.grey[250],
child: TextField(
controller: _textFieldController,
decoration: InputDecoration(
suffix: IconButton(
padding: EdgeInsets.all(0),
alignment: Alignment.bottomLeft,
icon: Icon(Icons.cancel),
onPressed: _onClear,
),
border: OutlineInputBorder(),
hintText: 'Blablabla',
),
)
);
}
There are three changes needed to reach the desired result:
Use suffixIcon instead of suffix
Remove vertical content padding, e.g. contentPadding: EdgeInsets.only(left:5) to vertically align the text when it is vertically constrained (e.g. the container height of 30).
Remove padding in the IconButton: padding: EdgeInsets.zero to align the icon.
The complete code is:
return Container(
width: 200,
height: 30,
color: Colors.grey[250],
child: TextField(
controller: _textFieldController,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 5),
suffixIcon: IconButton(
padding: EdgeInsets.zero,
icon: Icon(Icons.cancel),
onPressed: () => print("clear"),
),
border: OutlineInputBorder(),
hintText: 'Blablabla',
),
)
);
Final result:
Reduce the padding of the InputDecoration to zero.
TextField(
decoration: InputDecoration(
contentPadding: EdgeInsets.zero,

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.