Reputation: 1035
Is there a way to decrease the spacing between the actual input and the error text in a TextFormField widget? As it stands right now having error texts displayed on the form almost doubles the size of the form and I would like to keep the form area the same size with or without error text. From the pictures below you can see how much change it makes and that there is quite a lot of space between the input and the error message that could use reducing.
Form before errors Form after errors
Here is an example of one of the formfields
Padding(
padding: EdgeInsets.only(
top: 5.0, bottom: 5.0, left: 25.0, right: 25.0),
child: TextFormField(
focusNode: myFocusNodeName,
controller: signupNameController,
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.words,
style: TextStyle(
fontFamily: "WorkSansSemiBold",
fontSize: 16.0,
color: Colors.black),
decoration: InputDecoration(
border: InputBorder.none,
icon: Icon(
FontAwesomeIcons.user,
color: Colors.black,
),
errorText: signupLastNameErrorText,
hintText: "Last Name",
hintStyle: TextStyle(
fontFamily: "WorkSansSemiBold", fontSize: 16.0),
),
validator: (value) =>
value.isEmpty ? 'Last Name can\'t be empty' : null,
onSaved: (value) => _lastname = value,
),
),
Upvotes: 17
Views: 22267
Reputation: 1142
Another way would be to create a subclass of FormField
, handle validation and showing the error manually and delegate all other functionality down to TextFormField
.
class TextFormField2 extends FormField<String> {
final TextEditingController? controller;
final FocusNode? focusNode;
final TextStyle? style;
final int? minLines;
final int? maxLines;
final double subtextGap; // <-- Gap between input and error text
final TapRegionCallback? onTapOutside;
final void Function(String value)? onChanged;
TextFormField2(
{this.controller,
super.initialValue,
this.focusNode,
this.onTapOutside,
this.onChanged,
this.style,
this.minLines,
this.maxLines,
this.subtextGap = 2,
super.validator,
super.autovalidateMode = AutovalidateMode.onUserInteraction,
InputDecoration? decoration})
: super(
builder: (FormFieldState<String> state) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
controller: controller,
initialValue: state.value,
focusNode: focusNode,
onTapOutside: onTapOutside,
style: style,
minLines: minLines,
maxLines: maxLines,
decoration: decoration?.copyWith(
prefix: Container(
width:
(decoration.contentPadding as EdgeInsets?)?.left ?? 0,
),
contentPadding: EdgeInsets.only(
left: 0,
top: (decoration.contentPadding as EdgeInsets?)?.top ?? 0,
right:
(decoration.contentPadding as EdgeInsets?)?.right ??
0,
bottom:
(decoration.contentPadding as EdgeInsets?)?.bottom ??
0,
),
// Used to create space for the error message so when the validation
// error is shown, there is no jumpy behavior
// counterText: ' ',
// counterStyle: Styles.error,
),
onChanged: (value) {
state.didChange(value);
onChanged?.call(value);
},
),
if (state.hasError) ...[
SizedBox(height: subtextGap),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
state.errorText!,
style: Styles.error,
),
],
),
]
],
);
},
);
}
Upvotes: 1
Reputation: 1
I tried to change text height, but I noticed that the animation is jumping.
I found another solution. Problem located in material/input_decorator.dart file. In _RenderDecoration class. It contains:
static const double subtextGap = 8.0;
I copied all files, remove InputDecorationTheme and changed value to 0.0.
It also contains InputDecoration. I extended InputDecoration and remove override methods:
class CustomInputDecoration extends InputDecoration
And then i used it in the component:
TextFormField(
decoration: CustomInputDecoration(...)
My flutter version: 2.2.1. I noticed that flutter team often rewrites components, so be careful! There may be changes in next releases.
Upvotes: 0
Reputation: 32459
The vertical padding of errorText
is set in input_decorator.dart
:
final double helperErrorHeight =
!helperErrorExists ? 0 : helperError.size.height + subtextGap;
The subtextGap
is a static constant and equal to 8.0
. Unfortunately, there's no easy way to override that value.
Upvotes: 4
Reputation: 276
Add decoration in TextFormField Widget.
InputDecoration(
contentPadding: EdgeInsets.only(left: 11, right: 3, top: 14, bottom: 14),
errorStyle: TextStyle(fontSize: 9, height: 0.3),
)
Upvotes: 26
Reputation: 97
My solutions, You can using:
maxLength For each TextFeild, => You will have space you want when show error, Affter that you can transparent color counter, It Worked,
Upvotes: 1
Reputation: 2264
There seems to be no way to do it unless you open the source code of InputDecoration (on your sdk folder flutter/packages/flutter/lib/src/material/input_decorator.dart)
look for _buildError
wrap the Text with Container like
Container(
padding: EdgeInsets.only(bottom: 4),
child: Text(
widget.errorText,
style: widget.errorStyle,
textAlign: widget.textAlign,
overflow: TextOverflow.ellipsis,
maxLines: widget.errorMaxLines,
)
)
Upvotes: 3