flutter 复选框表单验证

wecizke3  于 2023-04-07  发布在  Flutter
关注(0)|答案(4)|浏览(188)

如何在Flutter Form中验证复选框?其他验证都可以正常工作,但复选框不显示Error。下面是我的代码:

FormField(
  validator: (value) {
    if (value == false) {
      return 'Required.';
    }
  },
  builder: (FormFieldState<dynamic> field) {
    return CheckboxListTile(
      value: checkboxValue,
      onChanged: (val) {
        if (checkboxValue == false) {
          setState(() {
            checkboxValue = true;
          });
        } else if (checkboxValue == true) {
          setState(() {
            checkboxValue = false;
          });
        }
      },
      title: new Text(
        'I agree.',
        style: TextStyle(fontSize: 14.0),
      ),
      controlAffinity: ListTileControlAffinity.leading,
      activeColor: Colors.green,
    );
  },
),
xqk2d5yq

xqk2d5yq1#

这个问题的一个更简洁的解决方案是创建一个扩展FormField<bool>的类
以下是我如何做到这一点:

import 'package:flutter/material.dart';

class CheckboxFormField extends FormField<bool> {
  CheckboxFormField(
      {Widget? title,
      FormFieldSetter<bool>? onSaved,
      FormFieldValidator<bool>? validator,
      bool initialValue = false,
      bool autovalidate = false})
      : super(
            onSaved: onSaved,
            validator: validator,
            initialValue: initialValue,
            builder: (FormFieldState<bool> state) {
              return CheckboxListTile(
                dense: state.hasError,
                title: title,
                value: state.value,
                onChanged: state.didChange,
                subtitle: state.hasError
                    ? Builder(
                        builder: (BuildContext context) => Text(
                          state.errorText ?? "",
                          style: TextStyle(
                              color: Theme.of(context).colorScheme.error),
                        ),
                      )
                    : null,
                controlAffinity: ListTileControlAffinity.leading,
              );
            });
}
zsohkypk

zsohkypk2#

如果你想把你的复选框直接放在你的表单小部件树中,你可以使用下面提供的解决方案与FormField小部件。而不是使用ListTile我使用行和列,因为我的表单需要不同的布局。

FormField<bool>(
  builder: (state) {
    return Column(
      children: <Widget>[
        Row(
          children: <Widget>[
            Checkbox(
              value: checkboxValue,
              onChanged: (value) {
                setState(() {
//save checkbox value to variable that store terms and notify form that state changed
                  checkboxValue = value;
                  state.didChange(value);
                });
              }),
            Text('I accept terms'),
          ],
        ),
//display error in matching theme
        Text(
          state.errorText ?? '',
          style: TextStyle(
            color: Theme.of(context).errorColor,
          ),
        )
      ],
    );
  },
//output from validation will be displayed in state.errorText (above)
  validator: (value) {
    if (!checkboxValue) {
      return 'You need to accept terms';
    } else {
      return null;
    }
  },
),
68bkxrlz

68bkxrlz3#

你可以尝试这样的东西:

CheckboxListTile(
  value: checkboxValue,
  onChanged: (val) {
    setState(() => checkboxValue = val
  },
  subtitle: !checkboxValue
      ? Text(
          'Required.',
          style: TextStyle(color: Colors.red),
        )
      : null,
  title: new Text(
    'I agree.',
    style: TextStyle(fontSize: 14.0),
  ),
  controlAffinity: ListTileControlAffinity.leading,
  activeColor: Colors.green,
);
2w2cym1i

2w2cym1i4#

上面的答案是正确的,但是,如果您希望显示与TextFormField小部件错误消息的默认布局更一致的错误消息,则将Text小部件 Package 在Padding小部件中,并给予十六进制颜色#e53935。
注意:您可能需要调整左侧填充以适应CheckboxListTile小部件也 Package 在Padding小部件中。
验证码:

bool _termsChecked = false;
    CheckboxListTile(
              activeColor: Theme.of(context).accentColor,
              title: Text('I agree to'),
              value: _termsChecked,
              onChanged: (bool value) => setState(() => _termsChecked = value),
              subtitle: !_termsChecked
                ? Padding(
                    padding: EdgeInsets.fromLTRB(12.0, 0, 0, 0), 
                    child: Text('Required field', style: TextStyle(color: Color(0xFFe53935), fontSize: 12),),)
                : null,
            ),

相关问题