创建的新文本字段与先前文本字段的值一起出现在 flutter 中

New Textfield created appear with previous textfield's value in flutter

我有这个小部件要注册。在里面我想要求注册 6 个输入,但由于屏幕上没有太多 space,我分成 2 对 3。我首先在一个表单中显示三个,当用户按下继续按钮时我显示其他 3。但是,当我按下继续按钮时,新的 3 对 TextField 出现,其值与之前的相同。他们将位置移动了一点。我不知道为什么会这样,因为这 6 个字段中的每一个都是不同的 Widget 函数。

我创建了两个变量 form1 和 form2 来保存不同的形式

@override
  void initState() {
    super.initState();
    form1 = <Widget>[
      firstForm(),
      Text("Or Sign Up with social media"),
      SizedBox(
        height: 20,
      ),
      socialMediaButtons(),
      SizedBox(
        height: 50,
      ),
      Text("Have an account? Login")
    ];
    form2 = <Widget>[
      secondForm(),
      Text("Or Sign Up with social media"),
      SizedBox(
        height: 20,
      ),
      socialMediaButtons(),
      SizedBox(
        height: 50,
      ),
      Text("Have an account? Login")
    ];
  }

所有文本字段的格式都与下面的文本字段相同,我只是更改了相应字段的变量。

Widget firstNameField() {
    return TextFormField(
      initialValue: "",
      decoration: InputDecoration(
          contentPadding: EdgeInsets.only(top: 10, left: 20, right: 20),
          border: InputBorder.none,
          hintText: "First Name",
          hintStyle: TextStyle(color: Colors.grey[400], fontSize: 15)),
      onChanged: (val) {
        setState(() => firstName = val);
      },
    );
  }

我将文本字段合并到两个小部件(firstForm 和 secondForm)中。 (显示为 firstForm 但它与 second 的格式相同,只是调用了其他小部件的函数)。

Widget firstForm() {
    return Column(
      children: <Widget>[
        emailPassField(),
        SizedBox(
          height: 50,
        ),
        continueButton(),
        SizedBox(
          height: 50,
        ),
      ],
    );
  }

然后这是按下时的继续按钮小部件。显示第二种形式。我将 step 变量更改为 2 以转到第二种形式。

Widget continueButton() {
    return ButtonTheme(
        minWidth: 185.0,
        height: 48.0,
        child: RaisedButton(
          color: Colors.black,
          textColor: Colors.white,
          child: Text("continue"),
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(50.0)),
          onPressed: () => setState(() => step = 2),
        ));
  }

当变量 step 改变时,我创建了这个函数 (getForm) 来调用并为列的子项显示正确的表单数组变量。

@override
  Widget build(BuildContext context) {
    return Material(
      child: Expanded(
        child: Stack(
          children: <Widget>[
            // banner with picture
            Positioned(
              child: banner(),
            ),
            // Login Elements Container
            Positioned(
              child: Container(
                margin: EdgeInsets.only(top: 300.0),
                decoration: BoxDecoration(
                    color: Colors.white,
                    boxShadow: [
                      BoxShadow(
                          color: Colors.grey.withOpacity(0.2),
                          spreadRadius: 5,
                          blurRadius: 20,
                          offset: Offset(0, 0))
                    ],
                    borderRadius: BorderRadius.only(
                        topRight: Radius.circular(50),
                        topLeft: Radius.circular(50))),
                child: Center(
                  child: Column(
                    children: getForm(step),
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
//functions for switching forms
  getForm(int form) {
    if (form == 1) {
      return form1;
    } else if (form == 2) {
      return form2;
    }
  }

这是表格第一步的样子。 first form

如果我没有在文本字段中输入任何数据并按下继续按钮,将出现具有正确文本字段的第二个表单,如下图所示。您可以看到它们具有正确的提示文本。 second form

但是,如果我在表单的第一步输入一些数据(在第二个表单的数据步骤 1 中看到),然后按继续按钮,在第二步中,文本字段将向下移动一点点并且在前面的文本字段中输入的相同值也会出现在其他文本字段中(第二个表单,数据步骤 2)。有人可以帮我吗,我不知道那里发生了什么?我希望你能理解代码并能帮助我。

second form with data step 1 second form with data step 2

您需要为每个 TextFormField 创建一个 TextEditingController

final _emailController = TextEditingController();
final _passwordController = TextEditingController();
...
final _cityController = TextEditingController();

...

// initState

...

// dispose of all TextEditingControllers
@override
void dispose {
  _emailController.dispose();
  ...
  _cityController.dispose();
  super.dispose();
}

// do this for every TextFormField
Widget firstNameField() {
  return TextFormField(
    // pass the corresponding controller, no need to set initial value if empty
    controller: _firstNameController,
    decoration: InputDecoration(
      contentPadding: EdgeInsets.only(top: 10, left: 20, right: 20),
      border: InputBorder.none,
      hintText: "First Name",
      hintStyle: TextStyle(color: Colors.grey[400], fontSize: 15)),
    onChanged: (val) {
      setState(() => firstName = val);
    },
  );
}

为每个 textfield 使用唯一的 TextEditingcontroller...这样,值就不会与其他文本字段值重叠。