如何在 TextFormField 中将函数作为验证器传递?

How to pass a function as a validator in a TextFormField?

我想知道我是否可以将函数作为验证器传递。我试过了,但没有结果。

  Widget Field(String changedValue, String label, bool isTextObscured) {
    return TextFormField(
      decoration: InputDecoration(labelText: label),
      validator: checkFieldEmpty,
    );
  }

  checkFieldEmpty(String fieldContent) {
    if(fieldContent.isEmpty) {
      return 'Ce champ est obligatoire.';
    }
    return null;
  }

也许函数 return 类型应该是 String? 以便它适合验证器原型!

  Widget Field(String changedValue, String label, bool isTextObscured) {
    return TextFormField(
      decoration: InputDecoration(labelText: label),
      validator: checkFieldEmpty,
    );
  }

 String? checkFieldEmpty(String? fieldContent) { //<-- add String? as a return type
    if(fieldContent.isEmpty) {
      return 'Ce champ est obligatoire.';
    }
    return null;
  }

在 Flutter 中更合适的方法

记住,flutter 是一种声明式语言。也就是说,您通过组合小部件树来构建您的应用程序。在这里,您正在使用 return 一个 Widget 的函数。那就是打破这个规则。相反,您应该声明自己的实现 TextField 小部件的自定义小部件。方法如下:

1。声明您的自定义小部件

// Declare your CustomTextField as a Stateless/Stateful Widget
class MyCustomTextField extends StatelessWidget {
  // Declare your custom vars, including your validator function
  final String? changedValue; 
  final String? label; 
  final bool? isTextObscured;
  final String? Function(String?)? validator;

  const MyCustomTextField({
    Key? key, 
    this.changedValue, 
    this.label,
    this.isTextObscured,
    this.validator,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      decoration: InputDecoration(labelText: label),
      validator: validator,
    );
  }
}

2。使用您的自定义小部件

现在您可以将此自定义小部件用作任何其他小部件的子部件:

class ParentWidget extends StatelessWidget {
  const ParentWidget({Key? key}) : super(key: key);

  // This is your custom validator function and can leave
  // anywhere ;)
  Stirng? customValidtaor(String? fieldContent) => fieldContent.isEmpty? 'Ce champ est obligatoire.': null

  @override
  Widget build(BuildContext context) {
    return MyCustomTextField(
      label: 'Some label'
      // declare the validator here...
      // valiator: (fieldContent) => fieldContent.isEmpty? 'Ce champ est obligatoire.': null
      // or use your custom validator function
      validator: customValidator,
    );
  }
}

这样做,即表示您尊重 Flutter 使用 Widget 组合的最佳实践;)

checkFieldEmpty() 方法添加字符串作为 return 类型,见下文

改为:

checkFieldEmpty(String fieldContent) {}

使用这个:

String checkFieldEmpty(String fieldContent) {}

完整代码示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appTitle = 'Form Validation Demo';

    return MaterialApp(
      title: appTitle,
      home: Scaffold(
        appBar: AppBar(title: Text(appTitle)),
        body: MyCustomForm(),
      ),
    );
  }
}

// Create a Form widget.
class MyCustomForm extends StatefulWidget {
  @override
  MyCustomFormState createState() {
    return MyCustomFormState();
  }
}

// Create a corresponding State class.
// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
  // Create a global key that uniquely identifies the Form widget
  // and allows validation of the form.
  //
  // Note: This is a GlobalKey<FormState>,
  // not a GlobalKey<MyCustomFormState>.
  final _formKey = GlobalKey<FormState>();

  Widget textField(String changedValue, String label, bool isTextObscured) {
    return TextFormField(
      decoration: InputDecoration(labelText: label),
      validator: checkFieldEmpty,
    );
  }

  String checkFieldEmpty(String fieldContent) {
    if (fieldContent.isEmpty) return 'Ce champ est obligatoire.';
    return null;
  }

  @override
  Widget build(BuildContext context) {
    // Build a Form widget using the _formKey created above.
    return Form(
      key: _formKey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          textField('changedValue', 'Enter Password', false),
          ElevatedButton(
            onPressed: () {
              // Validate returns true if the form is valid, or false otherwise.
              if (_formKey.currentState.validate()) {
                // If the form is valid,
                // perform further actions here
              }
            },
            child: Text('Submit'),
          ),
        ],
      ),
    );
  }
}