Flutter 中是否可以要求下拉选择作为表单验证的一部分?

Gre*_*Noe 7 dart flutter

我熟悉在 Flutter 中使用 TextFormField 进行表单验证,但是是否可以将 DropdownButton 集成到表单中并要求在提交之前选择其值之一?

基本上,将 DropdownButton 验证集成到这个基本的 Flutter 验证示例中:

https://flutter.io/cookbook/forms/validation/

小智 5

Dart 包已经为此提供了小部件 DropdownButtonFormField。以下是如何使用它的示例:

List<String> typeNeg = [
"One",
"Two",
"Three",];

String dropdownValue = "One";

DropdownButtonFormField<String>(
                    value: dropdownValue,
                    hint: Text("Type of business"),
                    onChanged: (String newValue) {
                      setState(() {
                        dropdownValue = newValue;
                      });
                    },
                    validator: (String value) {
                      if (value?.isEmpty ?? true) {
                        return 'Please enter a valid type of business';
                      }
                    },
                    items: typeNeg
                        .map<DropdownMenuItem<String>>((String value) {
                      return DropdownMenuItem<String>(
                        value: value,
                        child: Text(value),
                      );
                    }).toList(),
                    onSaved: (val) => setState(() => _user.typeNeg = val),
                  ),
Run Code Online (Sandbox Code Playgroud)

用户模型如下:

class User {
    int id;
    String name;
    String email;
    String typeNeg;

    User({this.id, this.name, this.email, this.typeNeg});

    factory User.fromJson(Map<String, dynamic> parsedJson) {
       return User(
           id: parsedJson["id"],
           name: parsedJson["name"] as String,
           email: parsedJson["email"] as String,
           typeNeg: parsedJson["typeNeg"] as String,
           );
     }
   save(){
       print("User saved");
   }
}
Run Code Online (Sandbox Code Playgroud)

要尝试验证器选项更改String dropdownValue = "One";String dropdownValue = null;


Edm*_*Tam 4

text_form_field.dartFlutter 源代码中的文件中,您可以看到这TextFormField只不过是在回调中FormField发出一个小部件。您可以使用类似的模式编写自己的。这是我的:TextFieldbuilderDropdownFormField

import 'package:flutter/material.dart';

class DropdownFormField<T> extends FormField<T> {
  DropdownFormField({
    Key key,
    InputDecoration decoration,
    T initialValue,
    List<DropdownMenuItem<T>> items,
    bool autovalidate = false,
    FormFieldSetter<T> onSaved,
    FormFieldValidator<T> validator,
  }) : super(
          key: key,
          onSaved: onSaved,
          validator: validator,
          autovalidate: autovalidate,
          initialValue: items.contains(initialValue) ? initialValue : null,
          builder: (FormFieldState<T> field) {
            final InputDecoration effectiveDecoration = (decoration ?? const InputDecoration())
                .applyDefaults(Theme.of(field.context).inputDecorationTheme);

            return InputDecorator(
              decoration:
                  effectiveDecoration.copyWith(errorText: field.hasError ? field.errorText : null),
              isEmpty: field.value == '' || field.value == null,
              child: DropdownButtonHideUnderline(
                child: DropdownButton<T>(
                  value: field.value,
                  isDense: true,
                  onChanged: field.didChange,
                  items: items.toList(),
                ),
              ),
            );
          },
        );
}
Run Code Online (Sandbox Code Playgroud)

关键是DropdownButton绑定onChangedfield.didChange。用法非常简单:

          DropdownFormField<String>(
            validator: (value) {
              if (value == null) {
                return 'Required';
              }
            },
            onSaved: (value) {
              // ...
            },
            decoration: InputDecoration(
              border: UnderlineInputBorder(),
              filled: true,
              labelText: 'Demo',
            ),
            initialValue: null,
            items: [
              DropdownMenuItem<String>(
                value: '1',
                child: Text('1'),
              ),
              DropdownMenuItem<String>(
                value: '2',
                child: Text('2'),
              )
            ],
          ),
Run Code Online (Sandbox Code Playgroud)

我从这个网站得到了这个想法。不同之处在于我的版本DropdownFormField更接近 Flutter 的本机实现(它扩展TextFormField而不是将其包装在 a 内StatefulWidget)。