【问题标题】:why does Flutter form reset all fields when I click submit?为什么点击提交时 Flutter 表单会重置所有字段?
【发布时间】:2021-03-13 16:44:11
【问题描述】:

我有一个 FORM 和 32 个 TEXTFORMFIELDS 和一个按钮来验证和导航到输出屏幕。

TextButton(
              onPressed: () {
                _formKey.currentState.save(); // I added this line which does nothing
                if (_formKey.currentState.validate()) {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) {
                        return OutputScreen();
                      },
                    ),
                  );
                } else {
                  _showAlert(context); // third partypackage alert function
                }
              },
              child: Text(
                'Calculate',
              ),
            ),

我的问题是,如果用户点击提交,有时它会重置所有字段,无论验证是真还是假;

这是我经过大量测试后发现的一件事,当用户输入一个文本字段时,输入键盘有一个“DONE”键,用户可以使用它来结束编辑。现在,如果用户没有使用它,只是点击了下一个字段进行输入并继续单击我创建的 subit 按钮,它会重置所有表单。

有什么想法吗? 或者有没有办法强制用户在完成输入后点击键盘上的“完成”。

提前致谢。

/////////////////////////////////////// //// 编辑:完整的代码示例 ///////////////////////////////////////// /

class CementInputPage extends StatefulWidget {
  @override
  _CementInputPageState createState() => _CementInputPageState();
}

class _CementInputPageState extends State<CementInputPage> {
  static const double sizedBoxHeight = 8;
  final _formKeyCement = GlobalKey<FormState>();
  CementData cementData = new CementData();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xFFDDDDDD),
      appBar: AppBar(
        title: Text("Cement Input Data"),
      ),
      body: SafeArea(
        child: Form(
          key: _formKeyCement,
          child: ListView(
            children: [
              // Header data
              WhiteBoxContainer( //container I created in another file
                boxTitle: 'Header',
                childWidget: Column(
                  children: [
                    //TODO: Validate date format
                    myStringTextInputRow('Date'),
                    SizedBox(height: sizedBoxHeight),
                    myStringTextInputRow('Operator Company'),
                    SizedBox(height: sizedBoxHeight),
                    myStringTextInputRow('Cement Contractor'),
                    SizedBox(height: sizedBoxHeight),
                    myStringTextInputRow('Well Name'),
                    SizedBox(height: sizedBoxHeight),
                    myStringTextInputRow('Field Name'),
                    SizedBox(height: sizedBoxHeight),
                    myStringTextInputRow('Rig'),
                    SizedBox(height: sizedBoxHeight),
                    myStringTextInputRow('Rig Supervisor'),
                    SizedBox(height: sizedBoxHeight),
                    myStringTextInputRow('Cement Supervisor'),
                    SizedBox(height: sizedBoxHeight),
                  ],
                ),
              ),
              //
              //Well data
              WhiteBoxContainer(
                boxTitle: 'Well Data',
                childWidget: Column(
                  children: [
                    Row(
                      children: [
                        Expanded(
                          child: TextFormField(
                            keyboardType:
                                TextInputType.numberWithOptions(decimal: true),
                            autovalidateMode:
                                AutovalidateMode.onUserInteraction,
                            decoration: InputDecoration(
                              border: OutlineInputBorder(),
                              labelText: "Section Depth (ft)",
                            ),
                            validator: (value) {
                              return sectionTDValidator(value);
                            },
                          ),
                        ),
                        checkInputStatus(InputValidationStatus.notValid),
                      ],
                    ),
                    SizedBox(height: sizedBoxHeight),
                    Row(
                      children: [
                        Expanded(
                          child: TextFormField(
                            keyboardType:
                                TextInputType.numberWithOptions(decimal: true),
                            autovalidateMode:
                                AutovalidateMode.onUserInteraction,
                            decoration: InputDecoration(
                              border: OutlineInputBorder(),
                              labelText: "Casing length (ft)",
                            ),
                            validator: (value) {
                              return casingLengthValidator(value);
                            },
                          ),
                        ),
                        checkInputStatus(InputValidationStatus.notValid),
                      ],
                    ),
              Container(
                child: TextButton(
                  onPressed: () {
                    _formKeyCement.currentState.save(); // line I added which did nothing
                    if (_formKeyCement.currentState.validate()) {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) {
                            return CementOutputScreen();
                          },
                        ),
                      );
                    } else {
                     //I want to show an alert dialog   
                  child: Text(
                    'Calculate',
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

    String sectionTDValidator(String value) {
    if (value.isNotEmpty) {
      cementData.sectionTD = double.parse(value);
      if (cementData.sectionTD < kMinWellDepth) {
        return 'Section Depth is too short!';
      } else if (cementData.sectionTD > kMaxWellDepth) {
        return 'Section depth is too long!';
      } else if (cementData.casingLength != null &&
          cementData.casingLength > cementData.sectionTD) {
        return 'Section depth is shorter than casing length!';
      }
    } else {
      cementData.sectionTD = null;
    }
    return null;
  }

  String casingLengthValidator(String value) {
    if (value.isNotEmpty) {
      cementData.casingLength = double.parse(value);
      if (cementData.casingLength < kMinWellDepth) {
        return 'Casing Length is too short!';
      } else if (cementData.casingLength > kMaxWellDepth) {
        return 'Casing Length is too long!';
      } else if (cementData.sectionTD != null &&
          cementData.casingLength > cementData.sectionTD) {
        return 'Casing Length is longer than section depth!';
      } else if (cementData.leadLength != null) {

        if (cementData.leadLength > cementData.casingLength) {
          return 'Casing length is shorter than lead length!';
        } else if (cementData.tailLength != null) {
          // check tail length
          if (cementData.tailLength > cementData.casingLength) {
            return 'Casing length is shorter than lead length!';
          } else if ((cementData.leadLength + cementData.tailLength) >
              cementData.casingLength) {
            return 'Casing length is shorter than total cement length!';
          }
        }
      } else if (cementData.shoeTrackLength != null &&
          cementData.shoeTrackLength >= cementData.casingLength) {
        return 'Shoe track length is >= casing length!';
      }
    } else {
      cementData.casingLength = null;
    }
    return null;
  }

  String shoeTrackLengthValidator(String value) {
    if (value.isNotEmpty) {
      cementData.shoeTrackLength = double.parse(value);
      if (cementData.casingLength != null &&
          cementData.shoeTrackLength >= cementData.casingLength) {
        return 'Shoe track length is >= casing length!';
      }
    } else {
      cementData.shoeTrackLength = null;
    }
    return null;
  }

  String stickUpLengthValidator(String value) {
    if (value.isNotEmpty) {
      cementData.stickUpLength = double.parse(value);
      if (cementData.stickUpLength > kMaxStickUpLength) {
        return 'Stick up length is too long!';
      }
    } else {
      cementData.stickUpLength = null;
    }
    return null;
  }
}

Row myStringTextInputRow(String labelText) {
  return Row(
    children: [
      Expanded(
        child: TextFormField(
          keyboardType: TextInputType.name,
          maxLines: 2,
          minLines: 1,
          decoration: InputDecoration(
            border: OutlineInputBorder(),
            labelText: labelText,
          ),
        ),
      ),
      checkInputStatus(InputValidationStatus.notCritical),
    ],
  );
}

Container checkInputStatus(InputValidationStatus inputStatus) {
  if (inputStatus == InputValidationStatus.notValid) {
    return Container(
      alignment: Alignment.centerLeft,
      padding: EdgeInsets.only(left: 3),
      child: Icon(
        Icons.clear,
        color: Colors.red[900],
        size: 18.0,
        semanticLabel: 'Feedback icon',
      ),
    );
  } else if (inputStatus == InputValidationStatus.valid) {
    return Container(
      alignment: Alignment.centerLeft,
      padding: EdgeInsets.only(left: 3),
      child: Icon(
        Icons.done,
        color: Colors.green[900],
        size: 18.0,
        semanticLabel: 'Feedback icon',
      ),
    );
  } else {
    return Container(
      alignment: Alignment.centerLeft,
      padding: EdgeInsets.only(left: 3),
      child: Icon(
        Icons.flaky,
        color: Colors.orange[700],
        size: 18.0,
        semanticLabel: 'Feedback icon',
      ),
    );
  }
  ;
}

【问题讨论】:

  • 可能是“ListView”,因为它在渲染我的自定义小部件“WhiteBoxContainer”时发生,它总是发生在同一个“WhiteBoxContainer”小部件中的所有孩子身上,而且每次都不一定相同。有时会发生一个,其他发生两个,其他没有发生?

标签: forms flutter validation dart flutter-test


【解决方案1】:

尝试将TextEditingController 添加到您的TextFormFields 并删除autovalidateMode

【讨论】:

  • 你有什么例子吗?或者关于如何将其应用于所有 32 个字段的任何想法.. 文档对我来说不是很清楚,这个表单花了很多精力,最初我认为颤振更容易和更快,但在这个表单之后它会更长
猜你喜欢
  • 2019-03-04
  • 1970-01-01
  • 2020-09-23
  • 1970-01-01
  • 2018-10-05
  • 2021-06-03
  • 2011-09-20
  • 1970-01-01
  • 2013-04-25
相关资源
最近更新 更多