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

Posted

技术标签:

【中文标题】创建的新文本字段与先前文本字段的值一起出现在颤动中【英文标题】:New Textfield created appear with previous textfield's value in flutter 【发布时间】:2021-03-02 12:50:40 【问题描述】:

我有这个小部件要注册。在里面我想要求注册 6 个输入,但由于屏幕上没有太多空间,我分成 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

【问题讨论】:

【参考方案1】:

您需要为每个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);
    ,
  );

【讨论】:

【参考方案2】:

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

【讨论】:

以上是关于创建的新文本字段与先前文本字段的值一起出现在颤动中的主要内容,如果未能解决你的问题,请参考以下文章

如何更改文本字段颤动中的值?

使用按钮单击生成文本字段小部件并保存文本输入颤动

如何在颤动中选择基于下拉项添加文本字段值

如何在文本字段颤动中删除 suffixIcon 的填充

如何在颤动中将焦点转移到下一个文本字段?

如何在颤动中以对象形式在列表中添加文本字段值