在 Flutter 开发中,输入框是与用户交互的核心组件之一,无论是登录注册、搜索框还是表单填写,都离不开 TextField 或其封装组件 TextFormField。本文将详细介绍输入框的核心属性、常用功能及实战用法,预计阅读时间5分钟,下面开始吧~
1. 基础概念
Flutter 提供了两个主要的输入框组件:
- TextField:基础输入框组件,提供基本的文本输入功能。
- TextFormField :继承自
TextField,增加了表单验证、自动保存等功能,适合在Form组件中使用。
两者核心属性基本一致,本文以 TextField 为例讲解,差异部分会单独说明。
2. 核心属性详解
核心属性的详解,我会按照分类归纳,如下:
2.1. 基本配置
| 属性名 | 类型 | 说明 |
|---|---|---|
controller |
TextEditingController |
控制输入框文本(获取、设置、监听文本变化) |
keyboardType |
TextInputType |
键盘类型(如数字、邮箱、手机号等) |
textInputAction |
TextInputAction |
键盘动作按钮(如完成、下一步、搜索) |
obscureText |
bool |
是否隐藏输入内容(密码框常用) |
maxLines |
int |
最大行数(单行输入设为 1,多行设为 null 或更大值) |
minLines |
int |
最小行数 |
maxLength |
int |
最大输入长度(会显示计数器) |
maxLengthEnforcement |
MaxLengthEnforcement |
超出长度时的处理方式(截断/禁止输入) |
scrollPhysics |
ScrollPhysics |
输入框内容滚动时的物理效果(如禁止滚动、总是可滚动等) |
textCapitalization |
TextCapitalization |
自动大写规则(如句子首字母大写、所有字母大写等) |
示例:基础配置
dart
TextField(
controller: _controller, // 绑定控制器
keyboardType: TextInputType.number, // 数字键盘
textInputAction: TextInputAction.done, // 键盘按钮为"完成"
obscureText: false, // 不隐藏文本
maxLines: 1, // 单行输入
maxLength: 11, // 最大长度11(如手机号)
// 多行输入时禁止滚动(内容超出时也不滚动)
scrollPhysics: NeverScrollableScrollPhysics(),
// 句子首字母自动大写(适合英文输入)
textCapitalization: TextCapitalization.sentences,
略......
)
2.2. 样式配置
| 属性名 | 类型 | 说明 |
|---|---|---|
style |
TextStyle |
输入文本的样式(字体、大小、颜色等) |
decoration |
InputDecoration |
输入框装饰(边框、提示文本、图标等) |
cursorColor |
Color |
光标颜色 |
cursorWidth |
double |
光标宽度 |
cursorHeight |
double |
光标高度 |
textAlign |
TextAlign |
文本对齐方式(左、中、右) |
textDirection |
TextDirection |
文本方向(从左到右/从右到左) |
strutStyle |
StrutStyle |
控制文本的基线对齐(解决不同字体大小导致的对齐问题) |
toolbarOptions |
ToolbarOptions |
长按文本时显示的工具栏选项(如复制、粘贴、剪切) |
selectionControls |
TextSelectionControls |
自定义文本选择控件(如替换系统默认的复制粘贴工具栏) |
示例:自定义样式
dart
TextField(
style: TextStyle(
fontSize: 16,
color: Colors.black87,
),
cursorColor: Colors.blue,
cursorWidth: 2,
textAlign: TextAlign.start,
decoration: InputDecoration(
hintText: "请输入用户名", // 提示文本
hintStyle: TextStyle(color: Colors.grey), // 提示文本样式
prefixIcon: Icon(Icons.person), // 左侧图标
border: OutlineInputBorder( // 边框样式
borderRadius: BorderRadius.circular(8),
),
contentPadding: EdgeInsets.symmetric(vertical: 12, horizontal: 16), // 内边距
),
// 仅允许复制和粘贴操作(禁用剪切)
toolbarOptions: ToolbarOptions(
copy: true,
paste: true,
cut: false,
),
// 自定义选择控件(需实现TextSelectionControls)
// selectionControls: CustomSelectionControls(),
略......
)
2.3. 交互控制
| 属性名 | 类型 | 说明 |
|---|---|---|
enabled |
bool |
是否启用输入框(false 时禁用,不可输入) |
readOnly |
bool |
是否只读(可点击但不可编辑,区别于禁用) |
autofocus |
bool |
是否自动获取焦点 |
focusNode |
FocusNode |
焦点控制器(手动管理焦点状态) |
onChanged |
Function(String) |
文本变化时触发(实时监听输入) |
onSubmitted |
Function(String) |
点击键盘动作按钮时触发(如点击"完成") |
onTap |
Function() |
点击输入框时触发 |
inputFormatters |
List<TextInputFormatter> |
输入格式化(限制输入内容,如只允许数字) |
onEditingComplete |
VoidCallback |
编辑完成时触发(区别于onSubmitted,不接收文本参数) |
onAppPrivateCommand |
Function(String, Map<String, dynamic>) |
处理私有命令(通常用于原生与Flutter交互时传递指令) |
enableIMEPersonalizedLearning |
bool |
是否允许输入法个性化学习输入内容(默认true) |
示例:
dart
TextField(
enabled: true, // 启用输入
readOnly: false, // 可编辑
autofocus: true, // 自动聚焦
onChanged: (value) {
print("输入变化:$value"); // 实时监听
},
onSubmitted: (value) {
print("提交内容:$value"); // 点击完成时触发
},
// 编辑完成时触发(如手动调用_controller.text后)
onEditingComplete: () {
print("编辑已完成");
// 通常配合焦点管理,如切换到下一个输入框
FocusScope.of(context).nextFocus();
},
// 禁用输入法个性化学习(适用于敏感输入场景)
enableIMEPersonalizedLearning: false,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly, // 只允许输入数字
],
略......
)
焦点管理
FocusNode 用于手动控制输入框的焦点状态,常见场景包括:切换输入框焦点、监听焦点变化、强制获取/失去焦点等。
示例:
dart
// 1. 初始化焦点节点
final FocusNode _usernameFocus = FocusNode();
final FocusNode _passwordFocus = FocusNode();
@override
void dispose() {
// 销毁焦点节点(避免内存泄漏)
_usernameFocus.dispose();
_passwordFocus.dispose();
super.dispose();
}
// 2. 监听焦点变化
void initState() {
super.initState();
_usernameFocus.addListener(() {
if (_usernameFocus.hasFocus) {
print("用户名输入框获取焦点");
} else {
print("用户名输入框失去焦点");
}
});
}
// 3. 组件中使用
Column(
children: [
TextField(
focusNode: _usernameFocus,
decoration: InputDecoration(hintText: "用户名"),
textInputAction: TextInputAction.next, // 键盘显示"下一步"
onSubmitted: (_) {
// 点击下一步时,将焦点切换到密码框
FocusScope.of(context).requestFocus(_passwordFocus);
},
),
TextField(
focusNode: _passwordFocus,
decoration: InputDecoration(hintText: "密码"),
obscureText: true,
),
ElevatedButton(
onPressed: () {
// 手动让密码框获取焦点
FocusScope.of(context).requestFocus(_passwordFocus);
// 或手动失去所有焦点(收起键盘)
// FocusScope.of(context).unfocus();
},
child: Text("操作焦点"),
),
],
)
2.4. 其他实用属性
| 属性名 | 类型 | 说明 |
|---|---|---|
autocorrect |
bool |
是否启用自动纠错(默认 true) |
autocompleteMode |
AutocompleteMode |
自动完成模式(如关闭、用户名、邮箱等) |
scrollPadding |
EdgeInsets |
滚动时的内边距(避免被键盘遮挡) |
enableInteractiveSelection |
bool |
是否允许长按选中文本(默认 true) |
mouseCursor |
MouseCursor |
鼠标悬停时的光标样式(桌面端开发常用) |
clipBehavior |
Clip |
内容超出输入框时的裁剪方式(如Clip.none不裁剪) |
restorationId |
String |
用于状态恢复(配合RestorationMixin保存/恢复输入状态) |
scribbleEnabled |
bool |
是否启用手写输入(iPad等支持Apple Pencil的设备) |
dart
TextField(
// 桌面端鼠标悬停时显示文本输入光标
mouseCursor: SystemMouseCursors.text,
// 内容超出时不裁剪(可能导致UI溢出,谨慎使用)
clipBehavior: Clip.none,
// 启用手写输入(iPad场景)
scribbleEnabled: true,
略......
)
3. 控制器TextEditingController的使用
TextEditingController 是控制输入框文本的核心工具,主要功能包括:
3.1. 获取输入文本
dart
// 初始化控制器
final TextEditingController _controller = TextEditingController();
// 获取文本(通常在按钮点击等事件中调用)
ElevatedButton(
onPressed: () {
String inputText = _controller.text;
print("用户输入:$inputText");
},
child: Text("获取输入"),
)
// 组件中绑定
TextField(controller: _controller)
3.2. 设置文本内容
dart
ElevatedButton(
onPressed: () {
// 直接设置文本
_controller.text = "默认文本";
},
child: Text("设置默认值"),
)
3.3. 清空文本
dart
ElevatedButton(
onPressed: () {
// 清空输入框
_controller.clear();
},
child: Text("清空输入"),
)
3.4. 监听文本变化
dart
@override
void initState() {
super.initState();
// 监听文本变化(实时响应输入)
_controller.addListener(() {
String currentText = _controller.text;
print("当前输入:$currentText");
// 可在这里实现实时验证,如输入长度判断
if (currentText.length > 5) {
print("输入长度超过5个字符");
}
});
}
@override
void dispose() {
// 销毁控制器(必须调用,避免内存泄漏)
_controller.dispose();
super.dispose();
}
3.5. 控制光标位置
dart
ElevatedButton(
onPressed: () {
// 将光标移动到文本末尾
_controller.selection = TextSelection.fromPosition(
TextPosition(offset: _controller.text.length),
);
},
child: Text("光标移至末尾"),
)
4. TextFormField与表单验证
TextFormField 用于 Form 组件中,支持表单验证,核心属性增加了 validator,例子如下:
dart
Form(
key: _formKey, // 表单key,用于触发验证
child: Column(
children: [
TextFormField(
decoration: InputDecoration(hintText: "请输入邮箱"),
keyboardType: TextInputType.emailAddress,
// 验证逻辑
validator: (value) {
if (value == null || value.isEmpty) {
return "请输入邮箱";
}
if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value)) {
return "请输入正确的邮箱格式";
}
return null; // 验证通过
},
),
ElevatedButton(
onPressed: () {
// 触发表单验证
if (_formKey.currentState!.validate()) {
// 验证通过,执行提交逻辑
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("提交成功")),
);
}
},
child: Text("提交"),
),
],
),
)
5. 实战技巧
-
解决键盘遮挡问题:
- 在
Scaffold中设置resizeToAvoidBottomInset: true(默认值),键盘弹出时自动调整布局。 - 结合
SingleChildScrollView等滑动组件包裹起来,使页面可滚动。 - 解决键盘弹出会遮挡输入框的问题,可以参考我之前的文章:传送门
- 在
-
自定义输入框样式:
- 通过
InputDecoration的border、focusedBorder、enabledBorder区分不同状态的边框样式。 - 示例:聚焦时显示蓝色边框,未聚焦时显示灰色边框。
- 通过
-
密码框切换显示/隐藏:
dart
bool _obscureText = true;
TextField(
obscureText: _obscureText,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(
_obscureText ? Icons.visibility : Icons.visibility_off,
),
onPressed: () {
setState(() {
_obscureText = !_obscureText;
});
},
),
),
)
- 限制输入类型 :
- 使用
inputFormatters配合FilteringTextInputFormatter限制输入(如数字、字母、禁止表情等)。
- 使用
6. 总结
TextField 和 TextFormField 是 Flutter 中处理文本输入的核心组件,通过 TextEditingController 可灵活控制文本内容,通过 FocusNode 可精准管理焦点状态。掌握输入框的样式定制、文本控制、焦点管理和表单验证,能显著提升用户体验。实际开发中,需注意控制器和焦点节点的生命周期管理(及时销毁,避免内存泄漏),并根据具体场景选择合适的组件配置。
本次分享就到这儿啦,我是鹏多多,深耕前端的技术创作者,如果您看了觉得有帮助,欢迎评论,关注,点赞,转发,我们下次见~
PS:在本页按F12,在console中输入document.getElementsByClassName('panel-btn')[0].click();有惊喜哦~
往期文章
- flutter-屏幕自适应插件flutter_screenutil教程全指南
- flutter-使用url_launcher打开链接/应用/短信/邮件和评分跳转等
- flutter图片选择库multi_image_picker_plus和image_picker的对比和使用解析
- 解锁flutter弹窗新姿势:dialog-flutter_smart_dialog插件解读+案例
- flutter-切换状态显示不同组件10种实现方案全解析
- flutter-详解控制组件显示的两种方式Offstage与Visibility
- flutter-使用AnimatedDefaultTextStyle实现文本动画
- flutter-使用SafeArea组件处理各机型的安全距离
- flutter-实现渐变色边框背景以及渐变色文字
- flutter-使用confetti制作炫酷纸屑爆炸粒子动画