DropdownButton 选择调用 Flutter 中其他字段的 onValidate 函数
Posted
技术标签:
【中文标题】DropdownButton 选择调用 Flutter 中其他字段的 onValidate 函数【英文标题】:DropdownButton selection calls the onValidate functions of other fields in Flutter 【发布时间】:2020-11-26 20:30:56 【问题描述】:不知道我错过了什么。选择下拉列表的值时,表单onVaidate()
被触发,因此我的其他字段显示错误。我怎样才能阻止它?这是代码
小部件构建(BuildContext 上下文) //返回脚手架( // appBar: AppBar(title: Text("Registration")), // body: Center(child: Text(widget.user.displayName)), // );
FirebaseUser user = widget.user;
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text("Registration"),
),
body: SafeArea(
top: false,
bottom: false,
child: Form(
key: _formKey,
autovalidate: true,
child: ListView(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
children: <Widget>[
TextFormField(
validator: (value) => value.isEmpty ? 'Name is Required' : null,
decoration: const InputDecoration(
icon: const Icon(Icons.person),
hintText: 'Enter your first and last name',
labelText: 'Name',
),
),
TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.phone),
hintText: 'Enter a phone number',
labelText: 'Phone',
),
initialValue: user.phoneNumber,
enabled: user.phoneNumber == null,
keyboardType: TextInputType.phone,
validator: (value) => value.isEmpty ? 'Phone number is Required' : null
// inputFormatters: [
// WhitelistingTextInputFormatter.digitsOnly,
// ],
),
TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.email),
hintText: 'Enter a email address',
labelText: 'Email',
),
initialValue: user.email,
enabled: user.email == null,
validator: (value) => value.isEmpty ? 'Email is Required' : null,
keyboardType: TextInputType.emailAddress,
),
TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.remove_red_eye),
hintText: 'Enter the Password',
labelText: 'Password',
),
keyboardType: TextInputType.text,
obscureText: true,
validator: (value) => value.isEmpty ? 'Password is Required' : null
),
FormField(
builder: (FormFieldState state)
return InputDecorator(
decoration: InputDecoration(
icon: const Icon(Icons.card_membership),
labelText: 'ID Type',
),
isEmpty: _profile.govId == null,
child: DropdownButtonHideUnderline(
child: DropdownButton(
value: _profile.govId,
isDense: true,
onChanged: (String newValue)
setState(()
_profile.govId = newValue;
state.didChange(newValue);
);
,
items: _govtIds.map((String value)
return DropdownMenuItem(
value: value,
child: Text(value),
);
).toList(),
),
),
);
,
),
TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.confirmation_number),
hintText: 'Enter your Governmenr ID number',
labelText: 'ID Number',
),
keyboardType: TextInputType.datetime,
validator: (value) => value.isEmpty ? 'ID Number is Required' : null
),
FormField(
builder: (FormFieldState state)
return InputDecorator(
decoration: InputDecoration(
icon: const Icon(Icons.business),
labelText: 'Block Info',
),
isEmpty: _profile.block == null,
child:
// Column(children: [RadioListTile(title: Text("A")),RadioListTile(title: Text("B"))]),
// Radio(
// value: 0,
// groupValue: _blocks,
// onChanged: (value)),
DropdownButtonHideUnderline(
child:
DropdownButton(
value: _profile.block,
isDense: true,
onChanged: (String newValue)
setState(()
_profile.block = newValue;
state.didChange(newValue);
);
,
items: _blocks.map((String value)
return DropdownMenuItem(
value: value,
child: Text(value),
);
).toList(),
),
),
);
,
),
TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.home),
hintText: 'Enter your Flat number',
labelText: 'Flat number',
),
inputFormatters: [LengthLimitingTextInputFormatter(3)],
validator: (value)
if (value.isEmpty)
return 'Flat number is Required';
else if (_profile.isValidHouseNumber() == false)
return 'Invalid flat number';
else
return null;
,
keyboardType: TextInputType.number,
onChanged:(value)
_profile.houseNo = value;
,
),
Padding(
padding: EdgeInsets.fromLTRB(38.0, 30.0, 0.0, 0.0),
child: SizedBox(
height: 50.0,
child: FlatButton(
// elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
color: Colors.green,
child: Text('Submit',
style: TextStyle(fontSize: 20.0, color: Colors.white)),
onPressed: _validateAndSubmit,
),
))
],
))),
);
【问题讨论】:
【参考方案1】:在验证功能中调用一个方法以返回 null 所有其他字段。这将清除验证。这是一个修复,但不能解决问题。
上面的代码好像没什么问题,能不能把其他字段的代码也加一下?
编辑:
所有其他字段验证的原因是父窗体小部件的autovalidate: true
属性。删除它并使用带有different keys
的表单将每个 TextFormField 包装起来。
例如,您的TextFormField
应如下所示:
Form(
key: _formKey[0],
child: TextFormField(
validator: (value) => value.isEmpty ? 'Name is Required' : null,
decoration: const InputDecoration(
icon: const Icon(Icons.person),
hintText: 'Enter your first and last name',
labelText: 'Name',
),
),
),
用Form包裹起来,_formKey声明为
List<GlobalObjectKey<FormState>> _formKey = new List(number_of_keys);
像这样调用相应的 setState:
_formKey[position].currentState.setState(());
并且不要忘记删除父窗体小部件。
【讨论】:
添加了完整的构建方法 不要将所有的 TextFormFields 包装在一个表单中,这不是好的代码。使用表单的不同键单独包装。这样可以确保可以单独验证字段而不影响其他字段。以上是关于DropdownButton 选择调用 Flutter 中其他字段的 onValidate 函数的主要内容,如果未能解决你的问题,请参考以下文章
选择项目时,颤振不更新放置在对话框中的 DropdownButton
Flutter - 如何在小部件测试中选择 DropdownButton 项
在 DropdownButton 中选择 Item 会导致 Flutter 抛出错误
从 DropdownItems 中选择值后,DropdownButton 值未更新。如何使用 selectedValue 更新默认值?