Trim() 在 Flutter 应用程序中默认情况下在表单中的任何 TextField 的输入值

Trim() input value of any TextField in a Form by default in flutter app

我有不同的表单字段,我想在触发 validator 方法之前默认 trim 表单字段的每个值。

我想实现这个的原因是因为如果我 运行 在 validator 方法被触发时输入值上的 regex ,正则表达式将 return由于输入值末尾无用的 space 字符,input_text.hasMatch 为 false。

例如。 alphaNumericText.hasMatch(val) 下面的代码将 return 为假,因为输入值末尾有一个无用的额外 space 字符。

final alphaNumericText = RegExp(r'^[a-zA-Z0-9]+$');

TextFormField(
                  keyboardType: TextInputType.text,
                  decoration: new InputDecoration(
                    labelText: 'Enter your nickname',
                  ),
                  validator: (val) {
                    if (val.isEmpty == true) {
                      return 'Nickname is required!';
                    }
                    if (alphaNumericText.hasMatch(val) == false) {
                      return 'Use alphanumeric characters only in nickname.';
                    }
                    return null;
                  },
                  onSaved: (val) => this.nickname = val,
                ),

注意 我不想通过修改 alphaNumericText RegExp 来在输入值末尾招待额外的 space 来实现此目的。我不想以这种方式实现这一目标。

我想要的是在调用 validator 方法之前默认 验证 表单中所有 TextFields 中的每个值。

Trim onChanged 回调中的文本值并将其分配回控制器。

正如@Darish 所建议的,这是它的示例代码。

但需要注意的是,如果修剪,需要在 text 末尾 select。这只有在不允许中间有空格的情况下才有效。

class _MyHomePageState extends State<MyHomePage> {
  final alphaNumericText = RegExp(r'^[a-zA-Z0-9]+$');
  final textController = TextEditingController();

  @override
  void dispose() {
    super.dispose();
    textController?.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextFormField(
          controller: textController,
          keyboardType: TextInputType.text,
          decoration: new InputDecoration(
            labelText: 'Enter your nickname',
          ),
          onChanged: (val) {
            final trimVal = val.trim();
            if (val != trimVal)
              setState(() {
                textController.text = trimVal;
                textController.selection = TextSelection.fromPosition(TextPosition(offset: trimVal.length));
              });
          },
          validator: (val) {
            if (val.isEmpty == true) {
              return 'Nickname is required!';
            }
            if (alphaNumericText.hasMatch(val) == false) {
              return 'Use alphanumeric characters only in nickname.';
            }
            return null;
          },
        ),
      ),
    );
  }
}

只需添加

inputFormatters: [WhitelistingTextInputFormatter(RegExp(r'[a-zA-Z0-9]'))],

as 属性 到 TextInputField 并且用户甚至无法输入 space 或白名单以外的任何其他字符 您还可以从验证器

中删除额外的检查

完整示例

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Center(
            child: TextFormField(
              inputFormatters: [WhitelistingTextInputFormatter(RegExp(r'[a-zA-Z0-9]'))],
              keyboardType: TextInputType.text,
              decoration: new InputDecoration(
                labelText: 'Enter your nickname',
              ),
              validator: (val) {
                if (val.isEmpty == true) {
                  return 'Nickname is required!';
                }
                return null;
              },
              onSaved: (val) {},
            ),
          ),
        ),
      ),
    );
  }
}

我在验证函数中使用了以下逻辑。我通过包装 TextFormField 创建了自定义无状态小部件。因为我想在我的应用程序中使用相同的样式 TextFormFieldvalidator 是我传递给那个无状态小部件的函数。

  validator: (value) {
    if(validator != null){
      if(obscureText){
        return validator(value);
      }else{
        return validator(value.trim());
      }
    }
    return null;
  },

您可以在 onFieldSubmittedonSaved 中使用相同的逻辑。将 obscureText 设置为 true 时忽略修剪。因为我们不希望 trim.

的密码