Flutter 获取多个文本字段值的最佳方法

Flutter 获取多个文本字段值的最佳方法,flutter,dart,Flutter,Dart,我正在制作一个数据采集应用程序,它有多个TextFields,大约超过12个。我正在使用一个表单密钥来验证所有这些。我需要所有文本字段的值,以便将它们保存到firestore。我该怎么做?这是我的密码: import 'package:flutter/material.dart'; class MainForm extends StatefulWidget { @override _MainFormState createState() => _MainFormState();

我正在制作一个数据采集应用程序,它有多个
TextField
s,大约超过12个。我正在使用一个表单密钥来验证所有这些。我需要所有文本字段的值,以便将它们保存到firestore。我该怎么做?这是我的密码:

import 'package:flutter/material.dart';

class MainForm extends StatefulWidget {
  @override
  _MainFormState createState() => _MainFormState();
}

class _MainFormState extends State<MainForm> {
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Center(
      child: SingleChildScrollView(
        child: Form(
          key: _formKey,
          child: Column(
            children: <Widget>[
              Text('Enter information about PG Owner'),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: TextField(
                  autofocus: true,
                  textCapitalization: TextCapitalization.words,
                  textAlignVertical: TextAlignVertical.center,
                  onTap: () {},
                  decoration: InputDecoration(
                      prefixIcon: Icon(Icons.face),
                      labelText: 'Enter Name of Owner',
                      border: OutlineInputBorder()),
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: TextFormField(
                  validator: (value) {
                    if (value.length < 15) {
                      return 'Address seems very short!';
                    }
                    return null;
                  },
                  keyboardType: TextInputType.text,
                  decoration: InputDecoration(
                      prefixIcon: Icon(Icons.room),
                      labelText: 'Enter full address of Owner',
                      border: OutlineInputBorder()),
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: TextFormField(
                  keyboardType: TextInputType.number,
                  validator: (value) {
                    if (value.length < 9) {
                      return 'Phone number must be 9 digits or longer';
                    }
                    return null;
                  },
                  decoration: InputDecoration(
                      prefixIcon: Icon(Icons.phone),
                      labelText: 'Phone number of Owner',
                      border: OutlineInputBorder()),
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: TextFormField(
                  validator: (value) {
                    if (value.isEmpty) {
                      return 'Please enter a valid email address';
                    }
                    if (!value.contains('@')) {
                      return 'Email is invalid, must contain @';
                    }
                    if (!value.contains('.')) {
                      return 'Email is invalid, must contain .';
                    }
                    return null;
                  },
                  keyboardType: TextInputType.emailAddress,
                  decoration: InputDecoration(
                      prefixIcon: Icon(Icons.mail_outline),
                      labelText: 'Enter Email',
                      border: OutlineInputBorder()),
                ),
              ),
              )
            ],
          ),
        ),
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
类MainForm扩展StatefulWidget{
@凌驾
_MainFormState createState()=>\u MainFormState();
}
类_MainFormState扩展状态{
final _formKey=GlobalKey();
@凌驾
小部件构建(构建上下文){
返回中心(
子:SingleChildScrollView(
孩子:表格(
键:_formKey,
子:列(
儿童:[
文本(“输入关于PG所有者的信息”),
填充物(
填充:常数边集全部(8.0),
孩子:TextField(
自动对焦:对,
textcapitalize:textcapitalize.words,
textAlignVertical:textAlignVertical.center,
onTap:(){},
装饰:输入装饰(
前缀:图标(Icons.face),
labelText:“输入所有者名称”,
边框:OutlineInputBorder()),
),
),
填充物(
填充:常数边集全部(8.0),
子项:TextFormField(
验证器:(值){
如果(值。长度<15){
return“地址似乎很短!”;
}
返回null;
},
键盘类型:TextInputType.text,
装饰:输入装饰(
前缀:图标(Icons.room),
labelText:“输入所有者的完整地址”,
边框:OutlineInputBorder()),
),
),
填充物(
填充:常数边集全部(8.0),
子项:TextFormField(
键盘类型:TextInputType.number,
验证器:(值){
如果(值。长度<9){
返回“电话号码必须为9位或更长”;
}
返回null;
},
装饰:输入装饰(
前缀:图标(Icons.phone),
labelText:'所有者的电话号码',
边框:OutlineInputBorder()),
),
),
填充物(
填充:常数边集全部(8.0),
子项:TextFormField(
验证器:(值){
if(value.isEmpty){
返回“请输入有效的电子邮件地址”;
}
如果(!value.contains('@')){
return“电子邮件无效,必须包含@”;
}
如果(!value.contains('.')){
return“电子邮件无效,必须包含”;
}
返回null;
},
键盘类型:TextInputType.emailAddress,
装饰:输入装饰(
前缀:图标(Icons.mail\u outline),
labelText:“输入电子邮件”,
边框:OutlineInputBorder()),
),
),
)
],
),
),
),
);
}
}

更新:我知道从
TextField
获取值的正确方法(我已经阅读了文档)是创建一个控制器。但是,在我的例子中,有14个
TextField
s需要我创建14个控制器。有更好的方法吗?

使用TextFormField中的控制器,可以获得TextFormField的值

TextEditingController emailEditingController = TextEditingController();
TextFormField(
  controller: emailEditingController,
  validator: (value) {
    if (value.isEmpty) {
      return 'Please enter a valid email address';
    }
    if (!value.contains('@')) {
      return 'Email is invalid, must contain @';
    }
    if (!value.contains('.')) {
      return 'Email is invalid, must contain .';
    }
    return null;
  },
  keyboardType: TextInputType.emailAddress,
  decoration: InputDecoration(
      prefixIcon: Icon(Icons.mail_outline),
      labelText: 'Enter Email',
      border: OutlineInputBorder()),
);
获取值,如:

String email=emailEditingController.text;
更新的答案

使用OnSubmited获取值

onSubmitted: (String value){email=value;},
您可以使用,不需要创建任何
textededitingcontroller
,除了提供其他优势外,还可以将业务逻辑与用户界面分离

dependencies:
  flutter_bloc: ^0.21.0
  form_bloc: ^0.4.1
  flutter_form_bloc: ^0.3.0
导入“包装:颤振/材料.省道”;
进口“包装:颤振团/颤振团.飞镖”;
导入“包装:颤振形式集团/颤振形式集团.dart”;
导入“包:form_bloc/form_bloc.dart”;
void main()=>runApp(MaterialApp(home:MainForm());
类MainFormBloc扩展了FormBloc{
final nameField=TextFieldBloc();
最终地址字段=TextFieldBloc(验证器:[
(value)=>value.length<15?“地址似乎很短!”:null,
]);
最终phoneNumberField=TextFieldBloc(验证器:[
(值)=>
value.length<9?“电话号码必须为9位或更长”:null,
]);
final emailField=TextFieldBloc(验证器:[validators.email]);
@凌驾
List get fieldBlocs=>[
nameField,
地址字段,
电话号码字段,
emailField,
];
@凌驾
流提交()异步*{
//调用[mainFormBloc.submit]时会调用此方法
//每个字段组都有一个有效值。
//你可以在firestore中保存它们。
打印(nameField.value);
打印(addressField.value);
打印(phoneNumberField.value);
打印(emailField.value);
产生currentState.toSuccess('数据保存成功');
//yield`currentState.toLoaded()`因为
//如果状态为“FormBlocSuccess”,则无法提交。
//在大多数情况下,你不需要这样做,
//因为你只想提交一次。
屈服currentState.toLoaded();
}
}
类MainForm扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回BlocProvider(
生成器:(上下文)=>MainFormBloc(),
孩子:建筑工人(
生成器:(上下文){
final formBloc=BlocProvider.of(上下文);
返回脚手架(
appBar:appBar(标题)
String contactNumber;
String pin;
return Form(
  key: _formKey,
  child: Column(
    children: <Widget>[
      TextFormField(
        onSaved: (String value){contactNumber=value;},
        keyboardType: TextInputType.phone,
        inputFormatters: [WhitelistingTextInputFormatter.digitsOnly],
        maxLength: 10,
        decoration: InputDecoration(
            labelText: "Enter Your Mobile Number",
            hintText: "Number",
            icon: Icon(Icons.phone_iphone)),
        validator: (value) {
          if (value.isEmpty || value.length < 10) {
            return 'Please Enter 10 digit number';
          }
          return null;
        },
      ),
      TextFormField(
        onSaved: (String value){pin=value;},
        keyboardType: TextInputType.phone,
        inputFormatters: [WhitelistingTextInputFormatter.digitsOnly],
        maxLength: 10,
        decoration: InputDecoration(
            labelText: "Enter Your PIN",
            hintText: "Number",
            icon: Icon(Icons.lock)),
        validator: (value) {
          if (value.isEmpty || value.length < 6) {
            return 'Please Enter 6 digit PIN';
          }
          return null;
        },
      ),
      Padding(
        padding: const EdgeInsets.symmetric(vertical: 16.0),
        child: RaisedButton(
            color: Colors.black,
            textColor: Colors.white,
            onPressed: () {
              if (_formKey.currentState.validate()) {
                ***_formKey.currentState.save();***
                bloc.loginUser(contactNumber, pin);
              }
            },
            child: Text('Login' /*style: TextStyle(fontSize: 30),*/)),
      )
    ],
  ),
);