验证 Flutter Form 中的不可见字段

Validate a non-visible field in Flutter Form

我有一个带有许多 dropdownformfield 和 textformfield 小部件的 Flutter Form,使用 validate: 方法验证这些小部件很简单。视野的验证是显而易见的。

但是,在许多形式中,可能需要验证不可见元素。例如,如果在 Form 中拍照,将只有一个拍照按钮,它将生成的文件名输入到 String var 中。在这种情况下,我需要验证 String var 和 return 按钮的验证结果(即在按钮下方显示“必填字段”),但当然 String var 不保存在任何表单域小部件中。

这就是说,我如何才能将按钮“包装”在包含 validator: 方法的小部件中,或者如何将验证器添加到按钮本身,然后向用户显示适当的验证消息UI?

谢谢!

您可以创建自己的 FormField:

class TakePictureFormField extends FormField<String> {
  /// Creates a [FormField] that contains an [ElevatedButton] to take a picture
  /// with the phone camera.
  ///
  /// The [String] value corresponds to the path of the picture taken.
  TakePictureFormField({
    Key? key,
    String? initialValue,
    FormFieldSetter<String>? onSaved,
    FormFieldValidator<String>? validator,
    bool enabled = true,
    AutovalidateMode? autovalidateMode,
    ButtonStyle? buttonStyle,
    void Function(String)? onChanged,
  }) : super(
          key: key,
          initialValue: initialValue,
          onSaved: onSaved,
          validator: validator,
          enabled: enabled,
          autovalidateMode: autovalidateMode,
          builder: (FormFieldState<String> field) {
            final currentValue = field.value;
            return InputDecorator(
              decoration: InputDecoration(
                border: InputBorder.none,
                errorText: field.errorText,
                errorBorder: OutlineInputBorder(
                  borderSide: BorderSide(
                    color: Theme.of(field.context).errorColor,
                  ),
                ),
              ),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  ElevatedButton(
                    style: buttonStyle,
                    onPressed: () async {
                      // Fake implementation to take a picture.
                      final value = await Future<String>.delayed(
                          const Duration(microseconds: 300),
                          () => 'my_path/to/image');

                      field.didChange(value);
                      if (onChanged != null) {
                        onChanged(value);
                      }
                    },
                    child: const Text('Take a Picture'),
                  ),
                  if (currentValue != null) Text(currentValue),
                ],
              ),
            );
          },
        );
}

然后像在任何其他 FormField 小部件中一样在 Form 中使用它:

TakePictureFormField(
  validator: (val) =>
    val == null || val.isEmpty ? 'Error invalid picture' : null,
)

Try the complete example on DartPad