【问题标题】:How can I only show one form field on the screen at a time in Flutter?如何在 Flutter 中一次只在屏幕上显示一个表单域?
【发布时间】:2020-11-17 22:46:05
【问题描述】:

我正在尝试创建一个一次只显示一个 textFormField 的表单。我创建了一个Form 和一个key: 和一个Container() 作为孩子。 Container() 调用了一个方法,该方法基于一个计数器返回一个 TextFormField 小部件,该计数器在我每次单击下一步按钮时都会递增。除了我在字段中输入的文本保留在每个字段更改之间之外,一切正常。这是我的相关代码:

...              
 Form(
   key: _formkey,
     child: Column(
         children: <Widget>[
             SizedBox(
                height: _height * .10,
                ),
             if (pageCount > 0 && pageCount <= 2)
             _createField(pageCount),
             RaisedButton(onPressed: ()=> _next()),

...

void _next() {
    if (pageCount < 10) {
      setState(() {
        pageCount++;
      });
    }
  }

...

Widget _createField(int count) {
    switch (count) {
      case 1:
        return TextFormField(
          textAlign: TextAlign.center,
          decoration: textInputDecoration.copyWith(
            hintText: 'name',
            hintStyle: TextStyle(
              color: Colors.grey[500],
              fontStyle: FontStyle.italic,
            ),
          ),
          validator: (val) => val.isEmpty ? 'enter your display name' : null,
          onChanged: (val) {
            setState(() => displayName = val);
          },
        );
        break;
      case 2:
        return TextFormField(
          textAlign: TextAlign.center,
          decoration: textInputDecoration.copyWith(
            hintText: 'email',
            hintStyle: TextStyle(
              color: Colors.grey[500],
              fontStyle: FontStyle.italic,
            ),
          ),
          validator: (val) => val.isEmpty ? 'enter an email' : null,
          onChanged: (val) {
            setState(() => email = val);
          },
        );
        break;
 
...

      default:
        return null;
    }
  }

提示文本和验证有效,唯一的问题是我输入的任何内容都会留在下一个字段中。我尝试使用TextEditingController 清除该字段,但也许我没有正确使用它,因为它要么不起作用,要么有时我收到一个错误,即控制器被调用为空。我不确定我会把它放在哪里。我的最终目标是在填写表格时保留屏幕空间。我愿意接受有关其他方式来实现此目的的建议。

【问题讨论】:

    标签: flutter


    【解决方案1】:
    final TextEditingController _controller = TextEditingController();
    
    @override
    void dispose() {
      _controller.dispose(); // DO NOT FORGET TO DISPOSE THE CONTROLLER
      super.dispose();
    }
    
    void _next() {
    if (pageCount < 10) {
      setState(() {
        if (_formkey.currentState.validate()) {
          // update the variable by saving the form
          _formkey.currentState.save();
          pageCount++;
        }
      });
    }
    
    Widget _createField(int count) {
        switch (count) {
          case 1:
            // set the text to the correct variable
            _controller.text = displayName ?? '';
            return Center(
              child: TextFormField(
                textAlign: TextAlign.center,
                decoration: InputDecoration().copyWith(
                  hintText: 'name',
                  hintStyle: TextStyle(
                    color: Colors.grey[500],
                    fontStyle: FontStyle.italic,
                  ),
                ),
                autovalidateMode: AutovalidateMode.onUserInteraction,
                controller: _controller,
                validator: (val) => val.isEmpty ? 'enter your display name' : null,
                // update the variable as the user navigates through the form
                onSaved: (val) => displayName = val,
              ),
            );
            break;
          case 2:
            _controller.text = email ?? '';
            return TextFormField(
              textAlign: TextAlign.center,
              decoration: InputDecoration().copyWith(
                hintText: 'email',
                hintStyle: TextStyle(
                  color: Colors.grey[500],
                  fontStyle: FontStyle.italic,
                ),
              ),
              autovalidateMode: AutovalidateMode.onUserInteraction,
              controller: _controller,
              validator: (val) => val.isEmpty ? 'enter an email' : null,
              onSaved: (val) => email = val,
            );
            break;
    ...
              default:
                _controller.text = '';
                setState(() => pageCount = 1);
                return null;
            }
          }
    

    【讨论】:

    • 感谢 Lee3,现在将 _controller 传递给该方法会清除该字段。但是我的验证器现在不工作。我还刚刚注意到,当我返回以前的字段时,它会将验证器错误保留在该字段下。有什么可以做的吗?
    • 我已更新我的答案,以验证 _next() 方法中的当前字段,然后允许用户进入下一个字段。我希望这会有所帮助。
    • 另外,使用您的解决方案,返回编辑字段也会将其清除
    • 您的编辑修复了验证。我标记为答案。谢谢!我想我可以忍受回去清理场地。除非你认为有办法解决这个问题?
    • 在您的 switch 案例中,将TextField 的当前值设置为相应变量的值,如果不为空。
    猜你喜欢
    • 2019-01-25
    • 1970-01-01
    • 2012-04-15
    • 2020-04-02
    • 2015-04-03
    • 1970-01-01
    • 2016-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多