我是Flutter(和Dart)的新手,在尝试构建用于编辑对象的表单时,我在网上搜索了示例和教程,而我看到了这两种用法。
2和有什么不一样?我应该使用哪一个?
谢谢。
Sur*_*gch 22
如果您不知道自己需要什么,请使用TextField. 这是最基本的 Flutter 小部件,用于从用户那里获取文本输入。这是你应该首先掌握的。
使用 aTextField是一种允许用户输入的简单方法。
TextField(
decoration: InputDecoration(
hintText: 'Name'
),
);
Run Code Online (Sandbox Code Playgroud)
要获取用户输入的文本,您可以在每次发生如下更改时收到通知:
TextField(
decoration: InputDecoration(
hintText: 'Name'
),
onChanged: (text) {
// do something with text
},
),
Run Code Online (Sandbox Code Playgroud)
或者你也可以使用TextEditingController,如所描述这里。这将使您可以访问文本状态。
如果您发现自己需要在保存之前验证用户文本输入,您可以考虑使用TextFormField. 想象一下这样的事情:
您可能希望对用户名和密码进行许多验证检查。
当然,您仍然可以只使用几个 TextField,但TextFormField具有额外的内置功能,可以让您的生活更轻松。通常,只有TextFormField在Form小部件内部使用时才会使用 a (尽管这不是严格要求)。
这是文档中的一个精简示例:
class MyCustomForm extends StatefulWidget {
@override
MyCustomFormState createState() {
return MyCustomFormState();
}
}
class MyCustomFormState extends State<MyCustomForm> {
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: <Widget>[
TextFormField(
validator: (value) {
// validation logic
},
),
RaisedButton(
child: Text('Submit'),
onPressed: () {
if (_formKey.currentState.validate()) {
// text in form is valid
}
},
),
],
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
anm*_*ail 17
如果
Form在需要保存,重置或验证操作的地方进行使用,请使用TextFormField。其他简单用户输入捕获TextField就足够了。
TextFormField,与Form小部件集成。
这是一个方便的小部件,将TextField小部件包装在FormField中。
一个Form不需要祖先。该表单使一次保存,重置或验证多个字段变得更加容易。
要在没有表单的情况下使用,请将GlobalKey传递给构造函数,然后使用GlobalKey.currentState保存或重置表单字段。
样品:
TextFormField(
decoration: const InputDecoration(
icon: Icon(Icons.person),
hintText: 'What do people call you?',
labelText: 'Name *',
),
onSaved: (String value) {
// This optional block of code can be used to run
// code when the user saves the form.
},
validator: (String value) {
return value.contains('@') ? 'Do not use the @ char.' : null;
},
)
Run Code Online (Sandbox Code Playgroud)
TextField,这是没有Form集成的基础文本字段。
onChanged每当用户更改字段中的文本时,文本字段就会调用回调。如果用户指示他们已完成在字段中的键入(例如,通过按软键盘上的按钮),则文本字段将调用onSubmitted回调。
Rub*_*elo 15
TextField是一个简单的文本字段。(您不关心用户输入)
TextFormField是要在表单中使用的文本字段(您关心用户输入)。
如果您不需要验证TextField. 如果您需要验证用户输入,请将 TextFormField 与validator.
我认为这可能是关于两者之间差异的最简洁明了的解释。
来自材料库:
TextField:材料设计文本字段。
TextFormField:FormField包含TextField.
同样,您可以包装FormField任何库比蒂诺输入组件,例如CupertinoTextField
下面是一个关于自定义的示例CheckboxFormField,它是FormField围绕材料设计组件的Checkbox:
// A custom CheckboxFormField, which is similar to the built-in TextFormField
bool agreedToTerms = false;
FormField(
initialValue: false,
validator: (value) {
if (value == false) {
return 'You must agree to the terms of service.';
}
return null;
},
builder: (FormFieldState formFieldState) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Checkbox(
value: agreedToTerms,
onChanged: (value) {
// When the value of the checkbox changes,
// update the FormFieldState so the form is
// re-validated.
formFieldState.didChange(value);
setState(() {
agreedToTerms = value;
});
},
),
Text(
'I agree to the terms of service.',
style: Theme.of(context).textTheme.subtitle1,
),
],
),
if (!formFieldState.isValid)
Text(
formFieldState.errorText ?? "",
style: Theme.of(context)
.textTheme
.caption
.copyWith(color: Theme.of(context).errorColor),
),
],
);
},
),
Run Code Online (Sandbox Code Playgroud)
经验法则:如果您的盒子只有一个输入字段,只需使用原材料输入即可TextField(FormField尽管在这种情况下有点矫枉过正)。如果您的框有许多输入字段,您需要将每个输入字段包装在 中FormField,然后将它们全部集成到Form小部件中,以获得一次性验证和保存所有表单字段的好处。
额外提示:如果您有一个TextField包裹在 a 中的组件FormField,不允许用户输入任何文本,例如 aCupertinoPickerFormField或 a SimpleDialogFormField,它为用户提供了多个选项之间的选择(这基本上是一个SimpleDialog包裹在 a 中的材质小部件FormField),只需使用不使用的 hintText参数来操作文本。使用 使提示文本的颜色与正常输入文本的颜色相同。InputDecorationTextEditingControllerhintStyle: const TextStyle(color: Color(0xdd000000))
来自 Flutter Europe 的这段视频将帮助您立即掌握 Flutter 中的表单。
TextFormField 对比 TextFieldTextFormField返回 a TextField,但包含了TextField额外的功能,您可以通过 a 使用Form,也可以不使用(例如重置、验证、保存等)。
通常,TextFormField除非您喜欢编写样板代码,否则您想使用它。
TextFormField工作?它能做什么?TextFormField扩展FormField类,(a StatefulWidget)。
FormField对象在实例化时会做一件特别的事情:它们在小部件树中查找 aForm并使用 that 注册自己Form。
注册后,这些FormField小部件可以由该父级更改Form。
Form也是一个StatefulWidget。它有一个FormState对象。
FormState可以获取和设置任何/所有FormFields注册到它的数据。
例如,要清除整个表格我们可以调用reset()上FormState,并FormState会通过所有的孩子重复FormFields登记,重设每一FormField它initialValue(默认为空)。
验证是将多个FormFieldlikeTextFormField放入 Form/ 的另一个常见用例FormState。这允许通过单个validate()调用来验证多个字段Form。
如何? FormState有一个validate()方法可以遍历每个注册FormField并调用该FormField's validate()方法。与手动跟踪所有内容并使用自定义代码单独验证每个validate()内容Form相比,一次调用要方便得多TextField。
FormField(等的基类TextFormField)在他们的build()方法中进行调用:
Form.of(context)?._register(this);
在英语中,这意味着:
搜索我的上下文层次结构,直到我们找到一个Form小部件(如果有)并使用该表单注册我自己。
这?是在没有Form小部件父级的情况下。的_register通话将只运行,如果有是一个Form与FormState上面的某个地方。
Form.of(context)?._register(this)工作?Form&FormState偷偷地使用InheritedWidget。在FormState.build() 你会看到这个代码:
return WillPopScope(
onWillPop: widget.onWillPop,
child: _FormScope( // ? sneaky
formState: this,
generation: _generation,
child: widget.child,
),
);
Run Code Online (Sandbox Code Playgroud)
看_FormScope我们看到:
class _FormScope extends InheritedWidget
Run Code Online (Sandbox Code Playgroud)
当父小部件是 时InheritedWidget,任何孩子都可以使用特殊的“为我找到此确切类型的父级”方法找到该父级。
以下是“find me”方法如何在内部使用/公开Form为我们可以从任何地方调用的静态方法:
static FormState of(BuildContext context) {
final _FormScope scope = context.dependOnInheritedWidgetOfExactType<_FormScope>();
return scope?._formState;
}
Run Code Online (Sandbox Code Playgroud)
该方法的命名dependOnInheritedWidgetOfExactType有点棘手。它会更易读findInheritedWidgetOfExactType,但它不仅仅是查找。(我们可以触发Form注册为dependOnthis的through children 的重建FormState)。
TextFormField是豪华套餐、空调、蓝牙连接的 8 扬声器立体声版本TextField。它包括许多您在接受用户输入的信息时会用到的常用功能。
| 归档时间: |
|
| 查看次数: |
5708 次 |
| 最近记录: |