How can I hide letter counter from bottom of TextField in Flutter - dart

I'm facing a small problem. As you can see, i have set maxLength 1 of TextField in Flutter, But i'm unable to hide bottom label of text counter.

To hide counter value from TextField or TextFormField widget while using maxLength attribute, try following:
TextField(
decoration: InputDecoration(
hintText: "Email",
counterText: "",
),
maxLength: 40,
),
In this, I have set counterText attribute inside InputDecoration property with empty value. Hope it will help.

This is the proper approach, it will prevent extra space below the Text Field, and also avoid extra code to set a null widget.
You can use input formatters in TextField
The following is:
inputFormatters:[
LengthLimitingTextInputFormatter(1),
]
Thank You!

you can use InputDecoratoin to hide letter counter.
TextFormField(
decoration: InputDecoration(
labelText: "username",
counterStyle: TextStyle(height: double.minPositive,),
counterText: ""
)

You can hide the counter by adding counterText: '', inside the textfield decoration. It will simply display an empty String.

Simply set counter to Offstage() will do the trick.
TextField(
maxLines: 1,
decoration: InputDecoration(
counter: Offstage(),
),
),

You can do:
TextField(
maxLength: 10,
buildCounter: (BuildContext context, { int currentLength, int maxLength, bool isFocused }) => null,
)

Most of the answers seem to work. Another way would be to assign the counter with a shrink SizeBox.
TextField(decoration: InputDecoration(
hintText: "Email",
counter: SizedBox.shrink()
),
maxLength: 40,
),

Add counterText: "", to InputDecoration
TextField(
decoration: InputDecoration(
counterText: "",
),
maxLength: 10,
),

Whenever you don't need something in flutter just put an empty container!
TextField(
decoration: InputDecoration(
hintText: "Email",
counter: Container(),
),
maxLength: 20,
),

Simply set buildCounter to null.
It is a callback that generates a custom [InputDecorator.counter] widget
TextField(
maxLength: (some length),
buildCounter: (BuildContext context, {int currentLength, int maxLength, bool isFocused}) => null,
);

This alone solved my problem!
TextField(
decoration: InputDecoration(
labelText: "Table Number",
counterText: ""
)

For null-safety use this:
TextField(
maxLength: 10,
buildCounter: (BuildContext context, {int? currentLength, int? maxLength, bool? isFocused}) => null,
)

You can use input formatters in TextField setting a limit to input and this is the best approach if you just want to hide the counter making a input limit.
import 'package:flutter/services.dart';
inputFormatters:[
LengthLimitingTextInputFormatter(1),
]
Or you can customize the decoration making a counter = Container():
decoration: InputDecoration(
hintText: "Email",
counter: Container(),
),
You if prefer to customize the buildCounter, here is how to do it properly (you can also customise the font, color etc). When you text field loses the focus the counter limits will disappears. Or you can just set
TextField(
controller: _clienteTextEditingController,
maxLength: 50,
buildCounter: (BuildContext context,
{int currentLength, int maxLength, bool isFocused}) {
return isFocused
? Text(
'The Input Limits are: $currentLength/$maxLength ',
style: new TextStyle(
fontSize: 10.0,
),
semanticsLabel: 'Input constraints',
)
: null;
},
),

you can use InputDecoratoin to hide the letter counter.
TextField(
keyboardType: TextInputType.number,
maxLength: 10,
decoration: InputDecoration(
**counterText:""**)
)

Another solution is to hide the counter widget by using SizedBox:
TextFormField(
...
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
counter: new SizedBox(
height: 0.0,
)),
...
)

You can follow the below codes.
TextField(
controller: myController,
maxLength: 3,
buildCounter: (BuildContext context, {int currentLength, int maxLength, bool isFocused}) =>null
)

Container(
height: 48,
alignment: Alignment.centerLeft,
padding: EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
border: Border.all(
color: CustomColors.kToDark,
),
color: CustomColors.White,
borderRadius: BorderRadius.all(Radius.circular(8))),
child: TextFormField(
textAlign: TextAlign.left,
cursorColor: CustomColors.kToDark,
maxLength: 30,
controller: _titleController,
keyboardType: TextInputType.text,
decoration: InputDecoration(
counterText: "",
border: InputBorder.none,
isDense: true,
contentPadding: EdgeInsets.all(0))),
),
Use counterText: "" inside InputDecoration()

In case you are still looking for the answer in 2020 here goes:
decoration: InputDecoration(
counter: Spacer(),
labelText: "National ID #",
border: InputBorder.none,
hintText: 'e.g 01-1234567A12',
hintStyle: TextStyle(color: Colors.grey)),
In the TextField, use a Spacer() as counter... hope this helps, i dont know if it breaks anything else but mine works fine.

Not pretty but works by removing the counter:
TextFormField(
buildCounter: (
BuildContext context, {
required int currentLength,
int? maxLength,
required bool isFocused,
}) => null,

Use a SizedBox.shrink() for the counter widget in InputDecoration:

Use a SizedBox with zero height and width:
TextField(
maxLength: 400,
decoration: InputDecoration(
counter: SizedBox(
width: 0,
height: 0,
),),)

As mentioned by #user10481267 in the best answer would be use buildCounter property. This gives extreme flexibility and you can even decide dynamically to show the counter or not.
I was building a dynamic form with the required properties in JSON. My implementation is as follows:
TextFormField(
buildCounter: (BuildContext context,
{
int currentLength,
int maxLength,
bool isFocused}) {
if (isFocused)
return formFields[index]["max"] == null
? null
: Text(
'$currentLength / $maxLength',
semanticsLabel: 'character count',
);
else
return null;
},
maxLength: formFields[index]["max"] ?? 100,
decoration: new InputDecoration(
labelText: formFields[index]["hint"] ?? "",
fillColor: Colors.green,
border: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(15.0),
borderSide: new BorderSide(),
),
)
)

Related

Use keyboard arrows to move to next textformfield

I have created a contact form with a few textformfields. When I'm using the keyboard I want to also use the the arrows at the top of the keyboard to move to next textformfield. I have already implemented TextInputAction.next so that when clicking on "return" you go to next textformfield, but I also want to include the arrows to do the same to go up/down.
The image below shows the arrows I want to include action on.
This is my current textformfield code:
Widget _createTextField(controller, keyboardType, int maxLength, int maxLines, String hintText, double screenWidth) {
return Expanded(
child: TextFormField(
scrollPadding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
textCapitalization: TextCapitalization.sentences,
textInputAction: TextInputAction.next,
style: TextStyle(fontSize: (screenWidth > maxMobileScreenWidth) ? 16 : 12),
controller: controller,
keyboardType: keyboardType,
maxLength: maxLength,
maxLines: maxLines,
validator: (value) {
if (value!.isEmpty) {
return '* Required field';
}
return null;
},
decoration: InputDecoration(
counterText: "",
filled: true,
hintText: hintText,
hintStyle: const TextStyle(color: Colors.black45),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(10.0)),
fillColor: const Color(0xff9ccb40),
),
),
);
}
You must use the Form() widget, on top of all your TextFromField.
you can use Form(child:Column(children:[])
suggest you to read this article

DropdownButtonFormField, with fixed width but dynamic text items

I don't think I understand constraints in Flutter that well so bear with me!
I want to DropdownButtonFormField that populates its items from DB. The string could be of any dynamic length. So what I have decided is to have a fixed width DropdownButtonFormField and DropdownMenuItem will have ellipsed Text.
Here is what I have tried.
SizedBox(
width: 136.0,
child: DropdownButtonFormField<int>(
hint: Text("hintText")
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(0.0),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
isDense: true),
items: [
DropdownMenuItem<int>(
value: 0,
child: TextOneLine(
"less character",
),
),
DropdownMenuItem<int>(
value: 0,
child: TextOneLine(
"mooooorrrrreeee character",
),
)
]
),
);
class TextOneLine extends StatelessWidget {
final String data;
final TextStyle style;
final TextAlign textAlign;
final bool autoSize;
TextOneLine(
String data, {
Key key,
this.style,
this.textAlign,
this.autoSize = false,
}) : this.data = data,
assert(data != null),
super(key: key);
#override
Widget build(BuildContext context) {
return Text(
data,
style: style,
textAlign: textAlign,
maxLines: 1,
overflow: TextOverflow.ellipsis,
);
}
}
I am getting overflow error
but when I click on DropdownButtonFormField the list of DropdownMenuItem are ellipsed.
How do I get rid of the Overflow error? I can't have Flexible or Expanded DropDownButtonFormField because the String length could be dynamic (could be longer than what could fit).
I know it might be a bit late to share the answer but I found an easy fix. Just add a isExpanded: true to the DropdownButtonFormField.
DropdownButtonFormField<int>(
hint: Text("hintText"),
isExpanded: true,
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(0.0),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
isDense: true),
items: [
DropdownMenuItem<int>(
value: 0,
child: Container(
width: 100,
child: TextOneLine(
"less character",
),
),
),
DropdownMenuItem<int>(
value: 0,
child: Container(
width: 100,
child: TextOneLine(
"mooooorrrrreeee character",
),
))
])
Before Adding isExpanded property
After Adding isExpanded property
Please refer the attached images, I've added 3 images.
Image 1: this is the issue you are getting.
Image 2: when I removed the width from SizedBox. Now it shows 3 boxes 1 is hint text and other is empty and 3rd is the drop-down arrow. I think the overflow is causing because of the 2nd empty space.
Image 3: Now in this, I've again added a width to SizedBox of 136 and put the SizedBox inside a Container having a fixed width size of 100 (is the width of the text in dropdown and it will wrap your text as per the width for sure). This resolved the overflow issue as per the code you have given.
I think as you have added a custom widget which is TextOneLine causing the issue. There may be some other workarounds but this solved the issue.
SizedBox(
width: 136,
child: DropdownButtonFormField<int>(
hint: Text("hintText"),
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(0.0),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
isDense: true),
items: [
DropdownMenuItem<int>(
value: 0,
child: Container(
width: 100,
child: TextOneLine(
"less character",
),
),
),
DropdownMenuItem<int>(
value: 0,
child: Container(
width: 100,
child: TextOneLine(
"mooooorrrrreeee character",
),
))
]),
)
Try out this and let me know whether this was the issue (and resolved) and please keep us updated any other workaround you done. Thanks
that's because you have an item in your list that consist of a too many characters
like "mooooorrrrreeee character" or something like that

How to align Hint Text into centre in Text Field?

i am trying to add alignment to the hint-text inside Text-field.but it is not working. How to bring it to centre??
How to write text in curved shape???
Container(
child: new TextFormField(
controller: _pass,
textAlign: TextAlign.center,
decoration: new InputDecoration.collapsed(
hintText: " PASSWORD", ), )),
use textAlign: TextAlign.center, inside TextFormField or textfield
here is the code
The Output Like This
My problem was the auto content padding:
TextField(
textAlign: TextAlign.center,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(0),
hintText: "hola mundo",
),
),
Happy coding.
The textHint will have the same Alignment as the input text. So you can try the code below to achieve what you're looking for:
TextFormField(
keyboardType: TextInputType.number,
maxLength: 5,
textAlign: TextAlign.center,
autofocus: true,
initialValue: '',
decoration: InputDecoration(
hintText: 'some hint',
counterText: "",
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5.0)),
),
);
Note: specific case, but might help others who tried everything else from this thread.
I had a design from which I copied all the paddings and alignments, but I somehow couldn't center the hint text, it was always a few pixels closer to the top edge.
The only thing that worked was finding out that there was a specific text height set in the design. After I applied that, everything aligned perfectly.
InputDecoration(
hintStyle: TextStyle(
fontSize: _smallFontSize, // or whatever
height: 1.4, // <----- this was the key
),
// other properties...
);
you can add textAlign: TextAlign.center to your code
here is my code and its works:
new Padding(
padding: new EdgeInsets.all(30.0),
child:
new TextField(
textAlign: TextAlign.center,
decoration: new InputDecoration(
border: new OutlineInputBorder(
borderSide: new BorderSide(color: Colors.teal)),
hintText: 'REF: 2',
),
),
),
all of the answers work for the fixed-sized text fields but in my case, I m using a dynamically sized container that parents my text field
AnimatedContainer(
width: (!widget.scrollController.hasClients ||
widget.scrollController.positions.length > 1)
? MediaQuery.of(context).size.width.toDouble()
: max(
MediaQuery.of(context).size.width -
widget.scrollController.offset.roundToDouble(),
(MediaQuery.of(context).size.width - 80.w).toDouble()),
duration: const Duration(milliseconds: 150),
constraints: BoxConstraints(maxHeight: 40.h),
margin: EdgeInsets.zero,
child: TextField(
controller: controller,
expands: true,
minLines: null,
maxLines: null,
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
filled: true,
fillColor: MyAppColors.primaryColor1,
border: UnderlineInputBorder(
borderRadius:
BorderRadius.circular(15.w)),
prefixIcon: Icon(
Icons.search,
size: 20.w,
color: Theme.of(context).accentColor,
),
hintText: 'Songs, albums or artists',
contentPadding: EdgeInsets.zero,
hintStyle:
Theme.of(context).textTheme.subtitle2!.copyWith(
color: Colors.white.withOpacity(0.8),
fontSize: 18.sp,
)),
),
);
the solution that worked for me is that I set expand parameter to true and set these parameters:
minLines: null,
maxLines: null,
expands: true,
textAlignVertical: TextAlignVertical.center
the min and max line must be set to null in order to expand.
that is the only solution I found cuz in another way my hint text gain extra padding even I set the content padding to zero my hint text is not centered in other screen sizes.
You can use following attribute of TextFormField:
textAlign: TextAlign.center
This used to work earlier but now it doesn't. There's a recently opened issue in flutter repo which you can follow
Edit
Now works as expected.
textAlign: TextAlign.center will move your focus too, i fix it with some empty spaces in hint text
hintText: ' this is centred text)',

How to limit number of characters in TextFormField?

Is there a way in dart language to keep the maximum input length fixed in TextFormField?
Use inputFormatters property. The following code would limit the textFormField to 42 in length :
new TextFormField(
inputFormatters: [
new LengthLimitingTextInputFormatter(42),
],
);
UPDATE: Import the package first. import 'package:flutter/services.dart';
use maxLength
TextFormField(
controller: _deskripsiController,
onFieldSubmitted: (String value){
setState(() {
_deskripsiController.text = value;
});
},
decoration: const InputDecoration(
border: const UnderlineInputBorder(),
labelText: "Deskripsi",
),
maxLength: 8,
)
best way is inputFormatters option:
inputFormatters: [
new LengthLimitingTextInputFormatter(11),// for mobile
],
Additionally to hahnsaja answer after you add maxLength - counter appears at the bottom of the TextFormField widget. To be able to hide it, add this to InputDecoration :
counterText: '',
counterStyle: TextStyle(fontSize: 0),
Example:
TextFormField(
controller: _deskripsiController,
onFieldSubmitted: (String value){
setState(() {
_deskripsiController.text = value;
});
},
decoration: const InputDecoration(
border: const UnderlineInputBorder(),
labelText: "Deskripsi",
counterText: '',
counterStyle: TextStyle(fontSize: 0),
),
maxLength: 8,
)

Multi-line TextField in Flutter

It may sound easy but How can we do a multi-line editable textfield in flutter? TextField works only with a single line.
Edit: some precisions because seems like it's not clear.
While you can set multiline to virtually wrap the text content, it's still not multiline. It's a single line displayed into multiple lines.
If you want to do something like this then you can't. Because you don't have access to ENTER button. And no enter button means no multiline.
To use auto wrap, just set maxLines as null:
TextField(
keyboardType: TextInputType.multiline,
maxLines: null,
)
If the maxLines property is null, there is no limit to the number of lines, and the wrap is enabled.
If you want your TextField be adapted to the user input then do this:
TextField(
keyboardType: TextInputType.multiline,
minLines: 1,//Normal textInputField will be displayed
maxLines: 5,// when user presses enter it will adapt to it
);
here you can set the max lines to whatever you want and you are good to go.
In my opinion setting the maxlines to null is not a good choice that's why we should set it to some value.
Although other people already mentioned that the keyboard type "TextInputType.multiline" can be used, I wanted to add my implementation of a TextField that automatically adapts its height when a new line is entered, as it is often desired to immitate the input behaviour of WhatsApp and similar apps.
I'm analyzing the number of '\n' chatacters in the input for this purpose each time the text is changed. This seems to be an overkill, but unfortunately I didn't find a better possibility to achieve this beahivour in Flutter so far and I didn't notice any performance problems even on older smartphones.
class _MyScreenState extends State<MyScreen> {
double _inputHeight = 50;
final TextEditingController _textEditingController = TextEditingController();
#override
void initState() {
super.initState();
_textEditingController.addListener(_checkInputHeight);
}
#override
void dispose() {
_textEditingController.dispose();
super.dispose();
}
void _checkInputHeight() async {
int count = _textEditingController.text.split('\n').length;
if (count == 0 && _inputHeight == 50.0) {
return;
}
if (count <= 5) { // use a maximum height of 6 rows
// height values can be adapted based on the font size
var newHeight = count == 0 ? 50.0 : 28.0 + (count * 18.0);
setState(() {
_inputHeight = newHeight;
});
}
}
// ... build method here
TextField(
controller: _textEditingController,
textInputAction: TextInputAction.newline,
keyboardType: TextInputType.multiline,
maxLines: null,
)
TextFormField(
minLines: 2,
maxLines: 5,
keyboardType: TextInputType.multiline,
decoration: InputDecoration(
hintText: 'description',
hintStyle: TextStyle(
color: Colors.grey
),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
),
),
),
While this question is rather old, there is no extensive answer that explains how to dynamically resize the TextField with little developer effort. This is especially of major importance when the TextField is either placed in a flexbox such as ListView, SingleChildScrollView, etc. (the flexbox will not be able to determine the intrinsic size of an expandable TextField).
As suggested by many other users, build your TextField like so:
TextField(
textInputAction: TextInputAction.newline,
keyboardType: TextInputType.multiline,
minLines: null,
maxLines: null, // If this is null, there is no limit to the number of lines, and the text container will start with enough vertical space for one line and automatically grow to accommodate additional lines as they are entered.
expands: true, // If set to true and wrapped in a parent widget like [Expanded] or [SizedBox], the input will expand to fill the parent.
)
How to cope with the missing intrinsic height of the TextField?
Wrap the TextField in a IntrinsicHeight class to provide the dynamically computed intrinsic height of the expandable TextField to its parent (when requested via e.g. flexbox).
1. Fixed height:
(A) Based on lines:
TextField(
minLines: 3, // Set this
maxLines: 6, // and this
keyboardType: TextInputType.multiline,
)
(B) Based on height:
SizedBox(
height: 200, // <-- TextField expands to this height.
child: TextField(
maxLines: null, // Set this
expands: true, // and this
keyboardType: TextInputType.multiline,
),
)
2. Flexible height:
Use a Column and wrap the TextField in Expanded:
Column(
children: [
Expanded(
child: TextField(
maxLines: null, // Set this
expands: true, // and this
keyboardType: TextInputType.multiline,
),
),
],
)
(Optional) Set decoration:
You can se this decoration to any of the above TextField:
decoration: InputDecoration(
hintText: 'Write a message',
filled: true,
)
You have to use this line in the TextField widget :
maxLines: null,
if didn't work , just note that you have to delete this :
textInputAction: TextInputAction.next
it's disable multi line property action in the keyboard ..
use this
TextFormField(
keyboardType: TextInputType.multiline,
maxLines: //Number_of_lines(int),)
This Code Worked for me, Also I'm able to use ENTER for web & mobile.
#override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
child: ConstrainedBox(
// fit: FlexFit.loose,
constraints: BoxConstraints(
maxHeight: height,//when it reach the max it will use scroll
maxWidth: width,
),
child: const TextField(
keyboardType: TextInputType.multiline,
maxLines: null,
minLines: 1,
decoration: InputDecoration(
fillColor: Colors.blueAccent,
filled: true,
hintText: "Type ",
border: InputBorder.none,
),
),
),
)
]);
}
TextField has maxLines property.
Use Expanded widget for dynamic feels
Expanded(
child: TextField(
keyboardType: TextInputType.multiline,
minLines: 1,
maxLines: 3,
),
)
if above once not worked for you then try add minLines also
TextField(
keyboardType: TextInputType.multiline,
minLines: 3,
maxLines: null);
For autowrap just use null for maxLines
TextFormField(
keyboardType: TextInputType.multiline,
maxLines: null,
)
or
TextField(
keyboardType: TextInputType.multiline,
maxLines: null,
)
Official doc states:
The maxLines property can be set to null to remove the restriction on the number of lines. By default, it is one, meaning this is a single-line text field.
NOTE: maxLines must not be zero.
Specify TextInputAction.newline to make a TextField respond to the enter key and accept multi-line input:
textInputAction: TextInputAction.newline,
use this
Expanded(
child: TextField(
controller: textMessageController,
keyboardType: TextInputType.multiline,
textCapitalization: TextCapitalization.sentences,
minLines: 1,
maxLines: 3,
onChanged: ((value) {
setState(() {
_messageEntrer = value;
});
}),
decoration: InputDecoration(
hintText: "Type your message here",
hintMaxLines: 1,
contentPadding:
const EdgeInsets.symmetric(horizontal: 8.0, vertical: 10),
hintStyle: TextStyle(
fontSize: 16,
),
fillColor: Colors.white,
filled: true,
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
borderSide: const BorderSide(
color: Colors.white,
width: 0.2,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
borderSide: const BorderSide(
color: Colors.black26,
width: 0.2,
),
),
),
),
),

Resources