CupertinoTextFormFieldRow

在不通过修改布局、大小或位置的情况下,对子组件施加虚拟效果的组件

CupertinoTextFormFieldRow是Flutter中Cupertino设计风格的一款文本输入组件。它将CupertinoTextField包裹在一个具有行标题的布局中,并通常包含一个左侧标题(prefix)和右侧的文本输入区域,整体呈现为iOS风格的一 行。这个组件专为模拟iOS应用中的设置列表或表单输入项而设计,用户可以在其中输入单行文本。

主要用途

  • 在iOS风格的应用中创建表单输入行。
  • 提供带有标签的文本输入框。
  • 方便地集成到Cupertino风格的设置页面或任何需要清晰标签文本字段的场景。

使用场景

  • 用户个人信息设置页: 输入姓名、邮箱、电话等。
  • 注册/登录表单: 用户名、密码输入。
  • 搜索框: 带标题的搜索输入。
  • 应用设置: 允许用户自定义某些文本设置(如默认消息)。

示例

基本用法

import 'package:flutter/cupertino.dart';

class BasicTextFormFieldRowExample extends StatefulWidget {
  const BasicTextFormFieldRowExample({super.key});

  
  State<BasicTextFormFieldRowExample> createState() => _BasicTextFormFieldRowExampleState();
}

class _BasicTextFormFieldRowExampleState extends State<BasicTextFormFieldRowExample> {
  final TextEditingController _nameController = TextEditingController();

  
  void dispose() {
    _nameController.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: const CupertinoNavigationBar(
        middle: Text('基本文本输入'),
      ),
      child: SafeArea(
        child: Column(
          children: <Widget>[
            const SizedBox(height: 20),
            CupertinoTextFormFieldRow(
              prefix: const Text('用户名', style: TextStyle(fontSize: 17.0)),
              placeholder: '请输入您的用户名',
              controller: _nameController,
              onChanged: (value) {
                print('用户名: $value');
              },
            ),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
              child: Text(
                '当前输入: ${_nameController.text}',
                style: const TextStyle(color: CupertinoColors.systemGrey),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

密码输入与验证器

import 'package:flutter/cupertino.dart';

class PasswordTextFormFieldRowExample extends StatefulWidget {
  const PasswordTextFormFieldRowExample({super.key});

  
  State<PasswordTextFormFieldRowExample> createState() => _PasswordTextFormFieldRowExampleState();
}

class _PasswordTextFormFieldRowExampleState extends State<PasswordTextFormFieldRowExample> {
  final TextEditingController _passwordController = TextEditingController();
  String? _errorMessage;

  
  void dispose() {
    _passwordController.dispose();
    super.dispose();
  }

  String? _validatePassword(String? value) {
    if (value == null || value.isEmpty) {
      return '密码不能为空';
    }
    if (value.length < 6) {
      return '密码至少需要6位';
    }
    return null; // 验证通过
  }

  
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: const CupertinoNavigationBar(
        middle: Text('密码输入'),
      ),
      child: SafeArea(
        child: Column(
          children: <Widget>[
            const SizedBox(height: 20),
            CupertinoTextFormFieldRow(
              prefix: const Text('密码', style: TextStyle(fontSize: 17.0)),
              placeholder: '请输入您的密码',
              controller: _passwordController,
              obscureText: true, // 密码遮蔽显示
              validator: _validatePassword,
              onChanged: (value) {
                setState(() {
                  _errorMessage = _validatePassword(value);
                });
              },
              // errorBuilder 用于显示错误信息
              errorBuilder: (_, String? errorText) {
                return errorText != null
                    ? Text(
                        errorText,
                        style: const TextStyle(color: CupertinoColors.systemRed, fontSize: 13.0),
                      )
                    : null;
              },
            ),
            if (_errorMessage != null)
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
                child: Text(
                  _errorMessage!, // 显示实时错误信息
                  style: const TextStyle(color: CupertinoColors.systemRed),
                ),
              ),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
              child: Text(
                '当前密码: ${_passwordController.text}',
                style: const TextStyle(color: CupertinoColors.systemGrey),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

带有修饰和键盘类型

import 'package:flutter/cupertino.dart';

class EmailTextFormFieldRowExample extends StatefulWidget {
  const EmailTextFormFieldRowExample({super.key});

  
  State<EmailTextFormFieldRowExample> createState() => _EmailTextFormFieldRowExampleState();
}

class _EmailTextFormFieldRowExampleState extends State<EmailTextFormFieldRowExample> {
  final TextEditingController _emailController = TextEditingController();

  
  void dispose() {
    _emailController.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: const CupertinoNavigationBar(
        middle: Text('邮箱输入'),
      ),
      child: SafeArea(
        child: Column(
          children: <Widget>[
            const SizedBox(height: 20),
            CupertinoTextFormFieldRow(
              prefix: const Text('邮箱', style: TextStyle(fontSize: 17.0)),
              placeholder: '请输入您的邮箱地址',
              controller: _emailController,
              keyboardType: TextInputType.emailAddress, // 设置键盘类型为邮箱
              textCapitalization: TextCapitalization.none, // 不自动大写
              autocorrect: false, // 不启用自动校正
              suffix: const Icon(CupertinoIcons.mail, color: CupertinoColors.secondaryLabel), // 右侧图标装饰
              onFieldSubmitted: (value) {
                print('已提交邮箱: $value');
              },
            ),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
              child: Text(
                '当前邮箱: ${_emailController.text}',
                style: const TextStyle(color: CupertinoColors.systemGrey),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

注意点

  • iOS风格适配: CupertinoTextFormFieldRow严格遵循iOS设计指南。如果你正在构建跨平台应用,可能需要判断平台来选择Material风格的TextFormFieldCupertino风格的此组件。
  • 控制器管理: 务必为controller属性提供TextEditingController实例,并在Statedispose方法中dispose该控制器,以避免内存泄漏。
  • 验证器(validator): 该组件提供了validator属性,用于实现输入验证逻辑。validator函数应返回null表示验证通过,返回一个String表示验证失败的错误信息。结合errorBuilder可以自定义错误信息的显示方式。
  • 键盘类型(keyboardType): 根据输入内容的类型(如文本、数字、邮箱、电话等)正确设置keyboardType可以提供更好的用户体验。
  • 焦点管理: 对于复杂的表单,可能需要使用FocusNode来手动管理焦点。
  • 高度自适应: CupertinoTextFormFieldRow的高度通常由其内容(如prefix和输入框)及其内部填充决定。如果需要调整行高,可能需要通过padding或包裹其他Widget来实现。
  • 无默认边框: 类似CupertinoTextFieldCupertinoTextFormFieldRow默认没有明显的边框。如果你需要边框,可以考虑在decoration属性中进行自定义,或在外部使用ContainerBoxDecoration包裹。

构造函数

const CupertinoTextFormFieldRow({
  super.key,
  this.prefix,
  this.padding = const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
  this.textInputAction,
  this.textCapitalization = TextCapitalization.none,
  this.keyboardType,
  this.strutStyle,
  this.textAlign = TextAlign.start,
  this.textAlignVertical,
  this.autofocus = false,
  this.readOnly = false,
  this.toolbarOptions,
  this.showCursor,
  this.obscuringCharacter = '•',
  this.obscureText = false,
  this.autocorrect = true,
  this.smartDashesType,
  this.smartQuotesType,
  this.enableSuggestions = true,
  this.maxLines = 1,
  this.minLines,
  this.expands = false,
  this.maxLength,
  this.maxLengthEnforcement,
  this.onChanged,
  this.onEditingComplete,
  this.onSubmitted,
  this.onAppPrivateCommand,
  this.inputFormatters,
  this.enabled,
  this.cursorWidth = 2.0,
  this.cursorHeight,
  this.cursorRadius = const Radius.circular(2.0),
  this.cursorColor,
  this.selectionHeightStyle = ui.BoxHeightStyle.tight,
  this.selectionWidthStyle = ui.BoxWidthStyle.tight,
  this.keyboardAppearance,
  this.scrollPadding = const EdgeInsets.only(bottom: 20.0),
  this.dragStartBehavior = DragStartBehavior.start,
  this.enableInteractiveSelection = true,
  this.selectionControls,
  this.onTap,
  this.scrollController,
  this.scrollPhysics,
  this.placeholder,
  this.placeholderStyle = const TextStyle(
    fontWeight: FontWeight.w400,
    color: CupertinoColors.placeholderText,
  ),
  this.prefixMode = OverlayVisibilityMode.always,
  this.clearButtonMode = OverlayVisibilityMode.never,
  this.controller,
  this.focusNode,
  this.decoration,
  this.paddingWhileEditing = const EdgeInsets.all(4.0),
  this.errorBuilder,
  this.validator,
  this.style,
  this.suffix,
  this.suffixMode = OverlayVisibilityMode.always,
  this.restorationId,
})

属性

属性名类型说明
controllerTextEditingController?控制文本字段的编辑行为,用于读取或设置文本内容。(重要)
prefixWidget?显示在输入框左侧的前缀小部件,通常是文本标签。(常用)
placeholderString?当输入框内容为空时显示的提示文本。
placeholderStyleTextStyle?placeholder 的样式。
obscureTextbool是否隐藏输入文本(如密码)。默认为 false(常用)
obscuringCharacterStringobscureTexttrue 时,用于遮蔽文本的字符,默认为
keyboardTypeTextInputType?弹出键盘类型,例如 TextInputType.emailAddressTextInputType.number(常用)
textInputActionTextInputAction?键盘右下角“完成”按钮的类型(如 done, next, search)。
onChangedValueChanged<String>?当文本内容改变时回调。(常用)
onEditingCompleteVoidCallback?当输入完成(用户按下键盘上的“完成”键)时回调。
onSubmittedValueChanged<String>?当用户提交文本(通常是按下键盘上的“完成”键)时回调,参数为最终文本。
validatorFormFieldValidator<String>?用于验证输入合法性的回调函数。返回 null 表示验证通过,返回 String 表示错误信息。(重要)
errorBuilderFormFieldErrorBuilder?构建自定义错误信息的Widget,传入错误文本。
maxLinesint?输入框最大的行数,默认为 1。设置为 null 或大于 1 的值可实现多行输入。
minLinesint?输入框最小的行数。
maxLengthint?允许输入的最大字符数。
autofocusbool是否自动获取焦点。默认为 false
readOnlybool是否只读。默认为 false
enabledbool?是否启用输入框。禁用时无法交互。
paddingEdgeInsetsGeometry组件内部的填充。默认为 EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0)
styleTextStyle?输入文本的样式。
cursorColorColor?光标的颜色。
decorationBoxDecoration?输入框的装饰样式(背景、边框、阴影等)。
suffixWidget?显示在输入框右侧的后缀小部件,如清除按钮(通常通过 clearButtonMode 控制)。
clearButtonModeOverlayVisibilityMode控制清除按钮的显示模式 (.always, .editing, .never)。
prefixModeOverlayVisibilityMode控制 prefix 的显示模式。
suffixModeOverlayVisibilityMode控制 suffix 的显示模式。
focusNodeFocusNode?用于手动管理输入框焦点。
scrollPaddingEdgeInsetsGeometry当输入框获取焦点时,为了确保其可见,滚动父级时会增加的填充量。

关键属性解释

  • controller: 这是与文本字段交互的核心。通过它,你可以获取当前输入文本(_controller.text)或设置新的文本(_controller.text = 'new value')。在StatefulWidget中使用时,请务必在dispose方法中调用_controller.dispose()以释放资源。
  • prefix: CupertinoTextFormFieldRow的一个设计亮点就是其左侧的prefix。它让你无需手动布局即可轻松地添加一个标签,使其在Cupertino表单中看起来非常自然和美观。
  • obscureText: 对于密码或敏感信息输入,将其设置为true会自动将输入的字符替换为obscuringCharacter(默认为 •),保护用户隐私。
  • validatorerrorBuilder: 这两个属性协同工作,提供了强大的输入验证和错误反馈机制。validator定义了验证规则,而errorBuilder则控制错误信息在UI中的展现形式,使得错误提示更加灵活和用户友好。
  • onChangedonSubmitted: onChanged用于实时响应文本变化,常用于即时搜索或验证;onSubmitted则响应用户明确的“完成”操作,适合在用户完成输入后触发逻辑,如表单提交。
  • keyboardType: 正确设置键盘类型是优化用户体验的关键。例如,为电话号码输入字段设置TextInputType.phone,会弹出带有数字和常用符号的键盘,方便用户输入。