[Flutter 基础] - Flutter基础组件 - TextField

940 阅读2分钟

TextField是一个接受键盘输入内容的组件,也就是我们平时口中的input输入框。它支持的属性非常丰富,不仅可以添加hint输入提示,还可以添加error提示、前缀、后缀以及输入内容校验,格式化等功能。这篇文章就是通过一些简单的示例来了解一下TextField的基本用法以及常用属性。

image.png

一、基础用法

  • 非选中状态

image.png

  • 选中输入状态

image.png

  • 代码片段
TextField(
  decoration: InputDecoration(
    labelText: '输入用户名', // 标签文字
    border: OutlineInputBorder(), // 边框样式
  ),
  onChanged: (value) { // 输入变化时触发
    print('输入内容:$value');
  },
);

核心属性

属性作用示例代码
controller控制文本内容(获取/设置值)TextEditingController _controller = TextEditingController();
decoration自定义输入框外观(边框、提示文字、图标等)InputDecoration(...)
keyboardType设置键盘类型(如数字、邮箱、多行等)keyboardType: TextInputType.number
obscureText隐藏输入内容(如密码输入)obscureText: true
maxLines设置最大行数(null 表示无限行)maxLines: 3maxLines: null
onChanged输入内容变化时触发的回调onChanged: (value) => print('输入内容:$value')
onSubmitted用户提交输入(如点击键盘完成按钮)时触发onSubmitted: (value) => print('提交内容:$value')
inputFormatters输入格式化(如限制输入类型或长度)inputFormatters: [FilteringTextInputFormatter.digitsOnly]

二、InputDecoration 样式定制

InputDecoration提供了非常丰富的输入框样式属性,通过属性的配置基本上可以满足开发中的大部分需求,所以了解InputDecoration的核心属性以及灵活运用好这些对日常开发还是有很大帮助的。

1. 常用属性

image.png

InputDecoration(
  hintText: '请输入内容', // 输入框提示文字
  labelText: '用户名', // 悬浮标签文字
  prefixIcon: Icon(Icons.person), // 输入框内左侧图标
  suffixIcon: Icon(Icons.clear), // 输入框内右侧图标
  errorText: '请输入有效内容', // 错误提示
  border: OutlineInputBorder(), // 边框样式
  contentPadding: EdgeInsets.all(12), // 内边距
);

2. 边框样式

  • 圆角边框

image.png

border: OutlineInputBorder(
  borderRadius: BorderRadius.circular(20),
),
  • 无边框

image.png

border: InputBorder.none,

3. 动态样式

  • 未选中

image.png

  • 选中

image.png

通过 ThemeData 或条件判断动态修改样式:

decoration: InputDecoration(
  enabledBorder: OutlineInputBorder(
    borderSide: BorderSide(color: Colors.blue),
  ),
  focusedBorder: OutlineInputBorder(
    borderSide: BorderSide(color: Colors.red),
  ),
),

还可以设置errorBorder, disabledBorder等,这些自带的属性减少了我们开发过程中去写很多的逻辑去判断。


三、输入类型与格式化

1. 键盘类型

image.png

// 数字键盘
TextField(
  keyboardType: TextInputType.number,
);

// 邮箱键盘
TextField(
  keyboardType: TextInputType.emailAddress,
);

// 多行输入
TextField(
  maxLines: null, // 自适应行数
  keyboardType: TextInputType.multiline,
);

2. 输入格式化

  • 仅允许数字

image.png

这个字母f的输入无效的
inputFormatters: [
  FilteringTextInputFormatter.digitsOnly,
],
  • 限制长度
    maxLength: 10, // 输入框右下角显示计数器
    maxLengthEnforced: true, // 禁止超过长度
    

3. 密码输入

image.png

TextField(
  obscureText: true, // 隐藏输入内容
  decoration: InputDecoration(
    suffixIcon: IconButton(
      icon: Icon(Icons.visibility),
      onPressed: () {}, // 切换显示密码
    ),
  ),
);

四、表单验证

1. 基础验证

TextFormFieldTextField的一个扩展,可以方便的完成针对表单中的某个输入框做基础的校验。 通过 validator 属性和 Form 组件实现:

image.png

// 定义表单键
final _formKey = GlobalKey<FormState>();

// 表单结构
Form(
  key: _formKey,
  child: Column(
    children: [
      TextFormField(
        validator: (value) {
          if (value == null || value.isEmpty) {
            return '请输入用户名';
          }
          return null;
        },
        decoration: InputDecoration(labelText: '用户名'),
      ),
      ElevatedButton(
        onPressed: () {
          if (_formKey.currentState.validate()) {
            // 验证通过,执行提交
          }
        },
        child: Text('提交'),
      ),
    ],
  ),
);

2. 复杂验证(如手机号)

image.png

validator: (value) {
  if (value == null || value.isEmpty) {
    return '手机号不能为空';
  }
  if (!RegExp(r'^1[3-9]\d{9}$').hasMatch(value)) {
    return '请输入有效的手机号';
  }
  return null;
}

五、控制器与焦点管理

1. TextEditingController

// 声明控制器
TextEditingController _controller = TextEditingController();

// 设置初始值
_controller.text = '初始文本';

// 获取输入内容
String inputValue = _controller.text;

// 释放资源
@override
void dispose() {
  _controller.dispose();
  super.dispose();
}

2. 焦点控制

// 声明焦点节点
FocusNode _focusNode = FocusNode();

// 跳转焦点
FocusScope.of(context).requestFocus(_focusNode);

// 监听焦点变化
_focusNode.addListener(() {
  if (_focusNode.hasFocus) {
    print('输入框获得焦点');
  }
});

六、完整示例代码

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('TextField 示例')),
        body: Padding(
          padding: EdgeInsets.all(16),
          child: Form(
            key: _formKey,
            child: Column(
              children: [
                // 带验证的文本输入
                TextFormField(
                  controller: _usernameController,
                  decoration: InputDecoration(
                    labelText: '用户名',
                    prefixIcon: Icon(Icons.person),
                    errorText: _usernameError,
                  ),
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return '请输入用户名';
                    }
                    return null;
                  },
                ),
                SizedBox(height: 16),

                // 密码输入
                TextFormField(
                  obscureText: true,
                  decoration: InputDecoration(
                    labelText: '密码',
                    suffixIcon: IconButton(
                      icon: Icon(Icons.visibility),
                      onPressed: () {},
                    ),
                  ),
                ),
                SizedBox(height: 16),

                // 数字输入
                TextField(
                  keyboardType: TextInputType.number,
                  inputFormatters: [FilteringTextInputFormatter.digitsOnly],
                  decoration: InputDecoration(
                    labelText: '年龄',
                    border: OutlineInputBorder(),
                  ),
                ),
                SizedBox(height: 16),

                // 多行输入
                TextField(
                  maxLines: 3,
                  keyboardType: TextInputType.multiline,
                  decoration: InputDecoration(
                    labelText: '留言',
                    border: OutlineInputBorder(),
                  ),
                ),
                SizedBox(height: 16),

                // 提交按钮
                ElevatedButton(
                  onPressed: () {
                    if (_formKey.currentState.validate()) {
                      print('提交成功');
                    }
                  },
                  child: Text('提交'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

总结

Flutter 的 TextField 是处理文本输入的核心组件,通过以下特性实现多样化需求:

  1. 基础功能:支持单行、多行、密码输入等场景。
  2. 样式定制:通过 InputDecoration 实现丰富的外观效果。
  3. 输入控制:结合 keyboardTypeinputFormatters 等限制输入类型。
  4. 表单验证:通过 validatorForm 实现动态验证。
  5. 高级功能:焦点管理、自动填充、防抖搜索等。

最佳实践

  • 使用 TextEditingController 管理输入内容。
  • 对于表单场景,优先使用 FormTextFormField
  • 通过 ThemeData 统一主题样式,避免重复代码。
  • 对敏感信息(如密码)使用 obscureText 和安全验证逻辑。