Flutter TextFormField 完全手册与设计最佳实践

目录

[1. 引言](#1. 引言)

[2. TextFormField 的基本用法](#2. TextFormField 的基本用法)

[3. 主要属性](#3. 主要属性)

[4. 自定义 TextFormField 样式](#4. 自定义 TextFormField 样式)

[4.1 设置边框样式](#4.1 设置边框样式)

[4.2 设置输入格式限制](#4.2 设置输入格式限制)

[4.3 多行输入](#4.3 多行输入)

[5. 结论](#5. 结论)

相关推荐


1. 引言

在 Flutter 中,TextFormFieldTextField 的扩展版本,专为表单输入设计。它除了继承 TextField 的所有功能外,还提供了输入验证、表单状态管理等功能,使其成为表单输入的最佳选择。本文将介绍 TextFormField 的基本用法、主要属性及自定义样式。

2. TextFormField 的基本用法

TextFormField 需要与 Form 组件一起使用,并通过 GlobalKey<FormState> 进行表单状态管理。

Dart 复制代码
final _formKey = GlobalKey<FormState>();

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

3. 主要属性

属性 说明
controller 获取和控制输入框的内容
decoration 自定义输入框外观,如边框、标签等
keyboardType 设置键盘类型(文本、数字、邮箱等)
obscureText 是否隐藏输入内容(密码输入)
validator 用于验证输入内容是否合法
onSaved 表单提交时保存输入值

示例:

Dart 复制代码
TextFormField(
  decoration: InputDecoration(hintText: '请输入密码'),
  obscureText: true,
  validator: (value) {
    if (value == null || value.length < 6) {
      return '密码长度至少为6位';
    }
    return null;
  },
)

4. 自定义 TextFormField 样式

4.1 设置边框样式

Dart 复制代码
TextFormField(
  decoration: InputDecoration(
    border: OutlineInputBorder(),
    labelText: '邮箱',
  ),
)

4.2 设置输入格式限制

Dart 复制代码
TextFormField(
  keyboardType: TextInputType.number,
  inputFormatters: [FilteringTextInputFormatter.digitsOnly],
)

4.3 多行输入

Dart 复制代码
TextFormField(
  maxLines: 5,
  decoration: InputDecoration(labelText: '留言'),
)

5. 结论

TextFormField 是 Flutter 中用于表单输入的增强版 TextField,支持输入验证、状态管理等功能,适用于用户注册、登录等场景。结合 Form 组件,可实现完整的表单交互,提高应用的可用性。一个完整的注册页面代码如下:

Dart 复制代码
import 'package:flutter/material.dart';

class ScRegisterPage extends StatefulWidget {
  @override
  _ScRegisterPageState createState() => _ScRegisterPageState();
}

class _ScRegisterPageState extends State<ScRegisterPage> {
  final _formKey = GlobalKey<FormState>();
  final _scaffoldKey = GlobalKey<ScaffoldState>();

  FocusNode _userNameNode = new FocusNode();
  FocusNode _pwdNode = new FocusNode();
  FocusNode _pwd2Node = new FocusNode();

  late String _username,_pwd,_pwd2;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(
        title: Text("注册"),
      ),
      //Form
      body: Form(
          key: _formKey,
          child: ListView(
            // 输入框会弹出软键盘,所以加个滑动的View
            padding: EdgeInsets.fromLTRB(22.0, 18.0, 22.0, 0.0),
            children: <Widget>[
              _buildUserName(),
              _buildPwd(),
              _buildPwd2(),
              _buildRegister(),
            ],
          )),
    );
  }

  Widget _buildUserName() {
    return TextFormField(
      focusNode: _userNameNode,
      //以用户名输入框 为默认焦点,则进入页面会自动弹出软键盘
      autofocus: true,
      decoration: InputDecoration(
        labelText: "用户名",
      ),
      //  如键盘动作类型
      textInputAction: TextInputAction.next,
      onEditingComplete: () {
        //按下action 的响应
        FocusScope.of(context).requestFocus(_pwdNode);
      },
      //校验
      validator: (value) {
        if (value!.trim().isEmpty) {
          //错误提示
          return "请输入用户名";
        }
        _username = value;
      },
    );
  }

  Widget _buildPwd() {
    return TextFormField(
      focusNode: _pwdNode,
      //以用户名输入框 为默认焦点,则进入页面会自动弹出软键盘
      autofocus: true,
      decoration: InputDecoration(
        labelText: "密码",
      ),
      //  如键盘动作类型
      textInputAction: TextInputAction.next,
      onEditingComplete: () {
        //按下action 的响应
        FocusScope.of(context).requestFocus(_pwd2Node);
      },
      //校验
      validator: (value) {
        if (value!.trim().isEmpty) {
          //错误提示
          return "请输入密码";
        }
        _pwd = value;
      },
    );
  }

  Widget _buildPwd2() {
    return TextFormField(
      focusNode: _pwd2Node,
      //以用户名输入框 为默认焦点,则进入页面会自动弹出软键盘
      autofocus: true,
      decoration: InputDecoration(
        labelText: "确认密码",
      ),
      //  如键盘动作类型
      textInputAction: TextInputAction.go,
      onEditingComplete: () {
        //按下action 的响应
        _click();
      },
      //校验
      validator: (value) {
        if (value!.trim().isEmpty) {
          //错误提示
          return "请确认密码";
        }

        if(_pwd != value){
          return "两次密码输入不一致";
        }
        _pwd2 = value;
      },
    );
  }

  Widget _buildRegister() {
    ///Container:装饰性容器
    return Container(
      height: 52.0,
      margin: EdgeInsets.only(top: 18.0),
      child: ElevatedButton(
        style: ElevatedButton.styleFrom(
          foregroundColor: Colors.white, // 文字颜色
          backgroundColor:Theme.of(context).primaryColor, // 背景色
        ),
        onPressed: _click,
        child: Text(
          "注册",
          style: TextStyle(color: Colors.white, fontSize: 18.0),
        ),
      ),
    );
  }

  _click() async{
    //点击注册按钮 让软键盘隐藏
    _userNameNode.unfocus();
    _pwdNode.unfocus();
    _pwd2Node.unfocus();

    //校验输入内容
    if (_formKey.currentState!.validate()) {
      //弹出一个加载框
      // barrierDismissible: 不允许按返回dismiss
      showDialog(context: context,barrierDismissible: false,builder: (_){
        return Center(child: CircularProgressIndicator(),);
      });

      //可以调用后端接口去注册了
      // var result =  await SccApi.register(_username,_pwd);
      // //对话框dismiss
      // Navigator.pop(context);
      // if(result['errorCode'] == -1){
      //   var error = result['errorMsg'];
      //   //弹出提示
      //   // Toast.show(error, context,gravity: Toast.CENTER);
      // }else{
      //   //Toast.show("注册成功!", context,gravity: Toast.CENTER);
      //   Navigator.pop(context);
      // }

    }
  }
}

相关推荐

Flutter 按钮组件 ElevatedButton 详解-CSDN博客文章浏览阅读1.1k次,点赞25次,收藏29次。本文详细描述 ElevatedButton 是 Flutter 中常见的按钮组件,适用于强调操作。通过 style 属性可以灵活地修改背景色、形状、大小等。掌握 ElevatedButton 的使用可以帮助开发者创建更美观的交互界面。_flutter button 组件https://shuaici.blog.csdn.net/article/details/146067694

Flutter TextField 从入门到精通:掌握输入框的完整指南-CSDN博客文章浏览阅读652次,点赞35次,收藏25次。本文全面解析 Flutter TextField 控件的使用技巧,覆盖从基础到进阶的完整知识体系。入门部分讲解基础属性(controller、decoration)、键盘类型设置和文本监听;进阶部分深入探讨表单验证(Form+TextFormField)、自定义输入格式(正则表达式验证)、动态样式修改(圆角/图标/动画)以及高级功能(输入长度限制、防抖处理)。通过代码示例演示手机号输入验证、密码隐藏切换、输入掩码等实战场景,并提供多平台适配、性能优化和无障碍访问等最佳实践方案。https://shuaici.blog.csdn.net/article/details/146068520

相关推荐
千里马学框架1 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台1 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone1 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc1 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
MoonMoonLee1 天前
小程序配置
小程序
ttyyttemo1 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077001 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
ai2work1 天前
ch23 综合复刻:从零做一个最小可用版本(capstone)
kotlin
其实防守也摸鱼1 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
ai2work1 天前
ch21 签名、校验与发版
kotlin