没错~ 嗯 拖了很久很久 没有更新了,最近又摸上了flutter,针对之前对TextField这个组件的一些用法做一下记录。
TextField被吐槽最多的应该就是他的高度了,无法调整高度、如何自适应等等情况。
我们看下这个组件的源码
class TextField extends StatefulWidget {
/// Creates a Material Design text field.
///
/// If [decoration] is non-null (which is the default), the text field requires
/// one of its ancestors to be a [Material] widget.
///
/// To remove the decoration entirely (including the extra padding introduced
/// by the decoration to save space for the labels), set the [decoration] to
/// null.
///
/// 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. [maxLines] must not be zero.
///
/// The [maxLength] property is set to null by default, which means the
/// number of characters allowed in the text field is not restricted. If
/// [maxLength] is set a character counter will be displayed below the
/// field showing how many characters have been entered. If the value is
/// set to a positive integer it will also display the maximum allowed
/// number of characters to be entered. If the value is set to
/// [TextField.noMaxLength] then only the current length is displayed.
///
/// After [maxLength] characters have been input, additional input
/// is ignored, unless [maxLengthEnforcement] is set to
/// [MaxLengthEnforcement.none].
/// The text field enforces the length with a [LengthLimitingTextInputFormatter],
/// which is evaluated after the supplied [inputFormatters], if any.
/// The [maxLength] value must be either null or greater than zero.
///
/// If [maxLengthEnforced] is set to false, then more than [maxLength]
/// characters may be entered, and the error counter and divider will
/// switch to the [decoration.errorStyle] when the limit is exceeded.
///
/// The text cursor is not shown if [showCursor] is false or if [showCursor]
/// is null (the default) and [readOnly] is true.
///
/// The [selectionHeightStyle] and [selectionWidthStyle] properties allow
/// changing the shape of the selection highlighting. These properties default
/// to [ui.BoxHeightStyle.tight] and [ui.BoxWidthStyle.tight] respectively and
/// must not be null.
///
/// The [textAlign], [autofocus], [obscureText], [readOnly], [autocorrect],
/// [maxLengthEnforced], [scrollPadding], [maxLines], [maxLength],
/// [selectionHeightStyle], [selectionWidthStyle], and [enableSuggestions]
/// arguments must not be null.
///
/// See also:
///
/// * [maxLength], which discusses the precise meaning of "number of
/// characters" and how it may differ from the intuitive meaning.
const TextField({
Key? key,
this.controller,
this.focusNode,
this.decoration = const InputDecoration(),
TextInputType? keyboardType,
this.textInputAction,
this.textCapitalization = TextCapitalization.none,
this.style,
this.strutStyle,
this.textAlign = TextAlign.start,
this.textAlignVertical,
this.textDirection,
this.readOnly = false,
ToolbarOptions? toolbarOptions,
this.showCursor,
this.autofocus = false,
this.obscuringCharacter = '•',
this.obscureText = false,
this.autocorrect = true,
SmartDashesType? smartDashesType,
SmartQuotesType? smartQuotesType,
this.enableSuggestions = true,
this.maxLines = 1,
this.minLines,
this.expands = false,
this.maxLength,
@Deprecated(
'Use maxLengthEnforcement parameter which provides more specific '
'behavior related to the maxLength limit. '
'This feature was deprecated after v1.25.0-5.0.pre.'
)
this.maxLengthEnforced = true,
this.maxLengthEnforcement,
this.onChanged,
this.onEditingComplete,
this.onSubmitted,
this.onAppPrivateCommand,
this.inputFormatters,
this.enabled,
this.cursorWidth = 2.0,
this.cursorHeight,
this.cursorRadius,
this.cursorColor,
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
this.keyboardAppearance,
this.scrollPadding = const EdgeInsets.all(20.0),
this.dragStartBehavior = DragStartBehavior.start,
this.enableInteractiveSelection = true,
this.selectionControls,
this.onTap,
this.mouseCursor,
this.buildCounter,
this.scrollController,
this.scrollPhysics,
this.autofillHints,
this.restorationId,
}) : assert(textAlign != null),
assert(readOnly != null),
assert(autofocus != null),
assert(obscuringCharacter != null && obscuringCharacter.length == 1),
assert(obscureText != null),
assert(autocorrect != null),
smartDashesType = smartDashesType ?? (obscureText ? SmartDashesType.disabled : SmartDashesType.enabled),
smartQuotesType = smartQuotesType ?? (obscureText ? SmartQuotesType.disabled : SmartQuotesType.enabled),
assert(enableSuggestions != null),
assert(enableInteractiveSelection != null),
assert(maxLengthEnforced != null),
assert(
maxLengthEnforced || maxLengthEnforcement == null,
'maxLengthEnforced is deprecated, use only maxLengthEnforcement',
),
assert(scrollPadding != null),
assert(dragStartBehavior != null),
assert(selectionHeightStyle != null),
assert(selectionWidthStyle != null),
assert(maxLines == null || maxLines > 0),
assert(minLines == null || minLines > 0),
assert(
(maxLines == null) || (minLines == null) || (maxLines >= minLines),
"minLines can't be greater than maxLines",
),
assert(expands != null),
assert(
!expands || (maxLines == null && minLines == null),
'minLines and maxLines must be null when expands is true.',
),
assert(!obscureText || maxLines == 1, 'Obscured fields cannot be multiline.'),
assert(maxLength == null || maxLength == TextField.noMaxLength || maxLength > 0),
// Assert the following instead of setting it directly to avoid surprising the user by silently changing the value they set.
assert(!identical(textInputAction, TextInputAction.newline) ||
maxLines == 1 ||
!identical(keyboardType, TextInputType.text),
'Use keyboardType TextInputType.multiline when using TextInputAction.newline on a multiline TextField.'),
keyboardType = keyboardType ?? (maxLines == 1 ? TextInputType.text : TextInputType.multiline),
toolbarOptions = toolbarOptions ?? (obscureText ?
const ToolbarOptions(
selectAll: true,
paste: true,
) :
const ToolbarOptions(
copy: true,
cut: true,
selectAll: true,
paste: true,
)),
super(key: key);
输入框的的样式修改都在这个类里面
this.decoration = const InputDecoration(),
const InputDecoration({
this.icon,
this.labelText,
this.labelStyle,
this.helperText,
this.helperStyle,
this.helperMaxLines,
this.hintText,
this.hintStyle,
this.hintTextDirection,
this.hintMaxLines,
this.errorText,
this.errorStyle,
this.errorMaxLines,
@Deprecated(
'Use floatingLabelBehavior instead. '
'This feature was deprecated after v1.13.2.'
)
this.hasFloatingPlaceholder = true,
this.floatingLabelBehavior,
this.isCollapsed = false,
this.isDense,
this.contentPadding,
this.prefixIcon,
this.prefixIconConstraints,
this.prefix,
this.prefixText,
this.prefixStyle,
this.suffixIcon,
this.suffix,
this.suffixText,
this.suffixStyle,
this.suffixIconConstraints,
this.counter,
this.counterText,
this.counterStyle,
this.filled,
this.fillColor,
this.focusColor,
this.hoverColor,
this.errorBorder,
this.focusedBorder,
this.focusedErrorBorder,
this.disabledBorder,
this.enabledBorder,
this.border,
this.enabled = true,
this.semanticCounterText,
this.alignLabelWithHint,
}) : assert(enabled != null),
assert(!(prefix != null && prefixText != null), 'Declaring both prefix and prefixText is not supported.'),
assert(!(suffix != null && suffixText != null), 'Declaring both suffix and suffixText is not supported.');
重点看着几个属性
contentPadding 主要是输入框的大小修饰
/// The padding for the input decoration's container.
///
/// The decoration's container is the area which is filled if [filled] is true
/// and bordered per the [border]. It's the area adjacent to [icon] and above
/// the widgets that contain [helperText], [errorText], and [counterText].
///
/// By default the `contentPadding` reflects [isDense] and the type of the
/// [border].
///
/// If [isCollapsed] is true then `contentPadding` is [EdgeInsets.zero].
///
/// If `isOutline` property of [border] is false and if [filled] is true then
/// `contentPadding` is `EdgeInsets.fromLTRB(12, 8, 12, 8)` when [isDense]
/// is true and `EdgeInsets.fromLTRB(12, 12, 12, 12)` when [isDense] is false.
/// If `isOutline` property of [border] is false and if [filled] is false then
/// `contentPadding` is `EdgeInsets.fromLTRB(0, 8, 0, 8)` when [isDense] is
/// true and `EdgeInsets.fromLTRB(0, 12, 0, 12)` when [isDense] is false.
///
/// If `isOutline` property of [border] is true then `contentPadding` is
/// `EdgeInsets.fromLTRB(12, 20, 12, 12)` when [isDense] is true
/// and `EdgeInsets.fromLTRB(12, 24, 12, 16)` when [isDense] is false.
final EdgeInsetsGeometry? contentPadding;
/// Whether the decoration is the same size as the input field.
///
/// A collapsed decoration cannot have [labelText], [errorText], an [icon].
///
/// To create a collapsed input decoration, use [InputDecoration.collapsed].
final bool isCollapsed;
翻译一下 下面这些话语
Whether the decoration is the same size as the input field.
翻译一下就是 是否和输入框一样的大小。
A collapsed decoration cannot have [labelText], [errorText], an [icon].
启用换行的输入框 不能有[labelText], [errorText], an [icon] 这些属性。
To create a collapsed input decoration, use [InputDecoration.collapsed].
如果要启用的话,需要使用到 [InputDecoration.collapsed]属性。
所以如果要取消默认的高度,那么就直接将这个属性isCollapsed启用就好了
下面来看下面的例子
class BorderText extends StatelessWidget {
final String text;
final bool password;
final Object onChanged;
const BorderText({
Key key,
this.text,
this.password,
this.onChanged,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return InkWell(
child: Container(
child: TextField(
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(10.0), // 设置自己的高度
isCollapsed: true, // 取消flutter的奇怪高度
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(width: 1.0, color: Colors.red),
),
hintText: this.text,
border: OutlineInputBorder(
borderSide: BorderSide(width: 1.0, color: Colors.black26),
)),
),
));
}
}
我们来看下
// 有边框的输入框
class BorderText extends StatelessWidget {
final String text;
final bool password;
final Object onChanged;
const BorderText({
Key key,
this.text,
this.password,
this.onChanged,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return InkWell(
child: Container(
child: TextField(
decoration: InputDecoration(
// contentPadding: const EdgeInsets.all(10.0), // 设置自己的高度
// isCollapsed: true, // 取消flutter的奇怪高度
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(width: 1.0, color: Colors.red),
),
hintText: this.text,
border: OutlineInputBorder(
borderSide: BorderSide(width: 1.0, color: Colors.black26),
)),
),
));
}
}
现在将代码注释拿掉在看下,莫名奇怪的输入框会大了很多,简直不要太难看
今天就先到这里吧,各位可以多多多textfleld的源码