首页 > 解决方案 > 如何在 Flutter 中一次只在屏幕上显示一个表单域?

问题描述

我正在尝试创建一个一次只显示一个 textFormField 的表单。我创建了一个Formwith a key:with aContainer()作为孩子。这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;
    }
  }

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

标签: flutter

解决方案


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;
        }
      }

推荐阅读