Flutter 如何传递用户';s TextFormField输入到颤振中不同类中的按钮

Flutter 如何传递用户';s TextFormField输入到颤振中不同类中的按钮,flutter,dart,Flutter,Dart,我正在创建一个颤振应用程序。为了代码的可重用性,我需要区分电子邮件和密码表单以及登录按钮,我不确定在单击表单时如何正确地将输入从textformfield传递到要验证的表单的按钮。这是我的密码。注意,我是颤振的初学者 //这是我的EmailTextForm类: class EmailTextForm extends StatelessWidget { String email; EmailTextForm({Key key, this.email}) : super(ke

我正在创建一个颤振应用程序。为了代码的可重用性,我需要区分电子邮件和密码表单以及登录按钮,我不确定在单击表单时如何正确地将输入从textformfield传递到要验证的表单的按钮。这是我的密码。注意,我是颤振的初学者

//这是我的EmailTextForm类:

    class EmailTextForm extends StatelessWidget {
    String email;

   EmailTextForm({Key key, this.email}) : super(key: key);

  Widget build(BuildContext context) {

return Container(
    width: 370.0,
    height: 54.0,
    child: TextFormField(
      decoration: InputDecoration(
        enabledBorder: OutlineInputBorder(
            //DEFAULT STATE OF THE BORDER(FOCUSED BORDER DOWN BELOW TO HAVE MORE CONTROL OF THE FORM)
            borderSide: BorderSide(
                width: 1.0, color: Color.fromRGBO(16, 25, 53, 0.1)),
            borderRadius: BorderRadius.circular(12.0)),
        focusedBorder: OutlineInputBorder(
          //ON FOCUSED BORDER TO NOT CHANGE STATE WHILE BEING PRESSED ON
          borderSide: BorderSide(
              width: 1.0, color: Color.fromRGBO(16, 25, 53, 0.1)),
          borderRadius: BorderRadius.circular(12.0),
        ),
        prefixIcon: Icon(Icons.mail, color: Color(0xFF9FA3AE)),
        hintText: 'El.Paštas',
        hintStyle: TextStyle(
          fontFamily: 'Sora',
          fontSize: 16.0,
          color: Color(0xFF9FA3AE),
        ),
      ),
      validator: (input) =>
          !input.contains('@') ? 'Please enter a valid email' : null,
      onSaved: (input) => email = input,
    ));
 }
}
//这是按钮类

import 'package:flutter/material.dart';
import 'dart:math' as math;

class LoginButton extends StatelessWidget {
  final _formKey = GlobalKey<FormState>();
  String email;
  String password;

  _submit() {
    if (_formKey.currentState.validate()) {
      _formKey.currentState.save();
      print('validated');
      //logging in the user
    }
  }

  @override
  Widget build(BuildContext context) {
    //Container to manipulate button design
    return Container(
        width: 370.0,
        height: 54.0,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular((12.0)),
          gradient: LinearGradient(
            //change gradient, wrong value, maybe something in AdobeXD.
            colors: <Color>[Color(0xFF00BAFF), Color(0xFF448CFA)],
            stops: [0.0, 1.0],
            begin: Alignment(-1.0, 0.0),
            end: Alignment(1.0, 0.0),
            transform: GradientRotation(math.pi / 2),
          ),
          boxShadow: [
            BoxShadow(
              color: Color.fromRGBO(48, 183, 241, 1.0),
              offset: Offset(0.0, 4.0),
              blurRadius: 12.0,
            ),
          ],
        ),

        //@@@@ WHEN BUTTON IS PRESSED @@@@
        child: ElevatedButton(
          onPressed: _submit,
          child: Text(
            'Prisijungti',
          ),
          style: ElevatedButton.styleFrom(
              //COLOR OF THE TEXT INSIDE THE BUTTON
              onPrimary: Color(0xFFFFFFFF),
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(12.0),
              ),
              primary: Colors.transparent,
              textStyle: TextStyle(
                //Text inside button style
                fontSize: 16.0,
                fontWeight: FontWeight.w600,
                fontFamily: 'Sora',
              )),
        ));
  }
}
导入“包装:颤振/材料.省道”;
导入'dart:math'作为数学;
类LoginButton扩展了无状态小部件{
final _formKey=GlobalKey();
字符串电子邮件;
字符串密码;
_提交(){
if(_formKey.currentState.validate()){
_formKey.currentState.save();
打印(“已验证”);
//登录用户
}
}
@凌驾
小部件构建(构建上下文){
//用于操纵按钮设计的容器
返回容器(
宽度:370.0,
身高:54.0,
装饰:盒子装饰(
边界半径:边界半径。圆形((12.0)),
梯度:线性梯度(
//改变梯度,错误的值,可能是AdobeXD中的某些东西。
颜色:[颜色(0xFF00BAFF),颜色(0xFF448CFA)],
停止:[0.0,1.0],
开始:对齐(-1.0,0.0),
结束:对齐(1.0,0.0),
变换:渐变旋转(math.pi/2),
),
boxShadow:[
箱形阴影(
颜色:颜色。来自RGBO(48183241,1.0),
偏移量:偏移量(0.0,4.0),
半径:12.0,
),
],
),
//@@@@当按下按钮时@@@@
儿童:升降按钮(
按下按钮:_提交,
子:文本(
“Prisijungti”,
),
样式:ElevatedButton.styleFrom(
//按钮内文本的颜色
onPrimary:颜色(0xFFFFFFFF),
形状:圆形矩形边框(
边界半径:边界半径。圆形(12.0),
),
原色:颜色。透明,
textStyle:textStyle(
//按钮样式中的文本
字体大小:16.0,
fontWeight:fontWeight.w600,
fontFamily:“索拉”,
)),
));
}
}

您需要将它们包装在表单小部件中并传递密钥,例如:

Form(
  key: _keyForm
  child: Column(
    children: <Widget>[
     EmailTextFieldForm(),
     PasswordTextFieldForm(),
     FormButton(),
   ],
 )
)
表单(
键:\ u键形式
子:列(
儿童:[
EmailTextFieldForm(),
PasswordTextFieldForm(),
FormButton(),
],
)
)

您需要将所有TextFormFields包装在一个表单中,这样才能得到它

Column(
  children: [
    TextFormField(),
    ....
    TextFormField(),
])
Builder(
  builder: (context) => Button(
    onTap: () {
      Form.of(context).validate()
    },
  ),
)
TextFormFields可以包装或移动到另一个小部件,只要它是表单的子项

如果一切都在一个小部件中

Form(
  child: 
     Column(
     children: [
       TextFormField(),
       ....
       TextFormField(),
       Button(
         onTap: () {},
       ),
])
您需要在生成器中包装该按钮,以便树中当前元素的上下文可用

Builder(
  builder: (context) => Button(
    onTap: () {},
  ),
),
然后,您可以执行
Form.of(context.validate()
。此条目将找到树中较高的第一个表单,并验证所有文本字段

这样你就应该这样出去

Column(
  children: [
    TextFormField(),
    ....
    TextFormField(),
])
Builder(
  builder: (context) => Button(
    onTap: () {
      Form.of(context).validate()
    },
  ),
)
如果按钮被放置在一个单独的小部件中,那么就不需要在构建器中包装它,您可以简单地调用验证,因为表单下面的上下文对您是可用的

Button(
  onTap: () {
    Form.of(context).validate()
  },
),
此外,还可以创建GlobalKey

并使用密钥验证。例如,您可以通过构造函数传递密钥(如果需要)

final_formKey=GlobalKey();
形式(
键:\ u formKey
子:列(
儿童:[
TextFormField(),
....
钮扣(
onTap:(){
_formKey.currentState!。验证()
}
)
],
),
)
访问字段数据 底部的代码示例显示了使用以下两种不同方式访问电子邮件字段值:

  • FormFieldState
  • text编辑控制器
这两种方法不依赖于使用
表单
包装字段(尽管这样做通常很方便,为处理表单数据和显示验证错误提供了更多选项)

为什么要使用
表单
表单
小部件包装字段对于将多个字段作为一个组处理/操作非常有用,例如表单重置、验证和提交

我们通过一个
GlobalKey
来访问这些
Form
函数,我们在声明
表单时将该函数提供给
Form

      child: Form(
        key: formKey, // declared above as a field in our State object
例如,
TextFormField
有一个
验证器:
参数(接受函数)。如果我们的字段位于
表单
中,我们可以要求
表单
调用所有验证器函数来“验证”我们的表单:

formKey.currentState.validate();
验证程序:
将显示您返回给它的任何非空字符串:

代码示例
导入“包装:颤振/材料.省道”;
类FormValuesPage扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(“形式值”),
),
正文:FormValuesExample(),
);
}
}
类FormValuesSample扩展StatefulWidget{
@凌驾
_FormValuesExampleState createState()=>_FormValuesExampleState();
}
类_FormValuesExampleState扩展状态{
GlobalKey formKey=GlobalKey();
GlobalKey emailFieldKey=GlobalKey();
TextEditingController emailController=TextEditingController();
@凌驾
无效处置(){
emailController.dispose();
super.dispose();
}
@凌驾
小部件构建(构建上下文){
返回填充(
填充:边缘组。对称(水平:20),
孩子:表格(
key:formKey,//上面声明为State对象中的字段
子:列(
mainAxisAlignment:mainAxisAlignment.space,
儿童:[
TextFormField(
键:emailFieldKey,
控制器:emailController,
装饰:输入装饰(
labelText:“电子邮件”