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

时间:2018-10-05 15:38:34

标签: dart flutter

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

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

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

2 个答案:

答案 0 :(得分:2)

从Flutter的源代码中的text_form_field.dart文件中,您可以看到TextFormField只不过是FormField,在其TextField回调中发出了builder小部件。您可以使用类似的模式编写自己的DropdownFormField。这是我的:

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(),
                ),
              ),
            );
          },
        );
}

关键是将DropdownButton的{​​{1}}绑定到onChanged。用法非常简单:

field.didChange

我从this site那里得到了这个主意。区别在于我的 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'), ) ], ), 版本更接近Flutter的本机实现(扩展了DropdownFormField而不是将其包装在TextFormField中)。

答案 1 :(得分:0)

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),
                  ),

用户模型如下:

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");
   }
}

要尝试验证程序选项,请将String dropdownValue = "One";更改为String dropdownValue = null;