如何在Flutter中验证表单

时间:2020-04-26 16:12:59

标签: flutter

我正在尝试验证自己的字段,然后再提交flutter。但是由于字段始终为空,因此验证始终为真,因此无法验证。

这是我尝试过的。有人可以帮助我确定我做错了什么吗?

如下所示,我什至设置了validatorscontroller。但是,即使字段为空,仍会提交

class _AddNewsState extends State<AddNews> {
  GlobalKey<FormState> _key = GlobalKey<FormState>();

  TextEditingController _headlineController;
  TextEditingController _descriptionController;
  String _dropDownActivity;

  // get current date
  static var now = new DateTime.now();
  static var formatter = new DateFormat('yyyy-MM-dd');
  String formattedDate = formatter.format(now);

  // get current timie
  dynamic currentTime = DateFormat.jm().format(DateTime.now());

  @override
  void initState() {
    super.initState();
    _headlineController = TextEditingController();
    _descriptionController = TextEditingController();
    _dropDownActivity = "";
  }

  @override
  Widget build(BuildContext context) {
    File _image;
    String image_url = "";

    FileImage _getImage() {
      var img = (File(widget.imgPath));
      setState(() {
        _image = img;
      });
      return FileImage(_image);
    }

    Future _showToastMsg(String msgType, String msg) {
      if (msgType == "success") {
        return Fluttertoast.showToast(
          msg: msg,
          textColor: Colors.white,
          toastLength: Toast.LENGTH_SHORT,
          timeInSecForIosWeb: 1,
          gravity: ToastGravity.BOTTOM,
          backgroundColor: Colors.green,
        );
      } else if (msgType == "error") {
        return Fluttertoast.showToast(
          msg: msg,
          textColor: Colors.white,
          toastLength: Toast.LENGTH_SHORT,
          timeInSecForIosWeb: 1,
          gravity: ToastGravity.BOTTOM,
          backgroundColor: Colors.red,
        );
      } else {
        return Fluttertoast.showToast(
          msg: msg,
          textColor: Colors.white,
          toastLength: Toast.LENGTH_SHORT,
          timeInSecForIosWeb: 1,
          gravity: ToastGravity.BOTTOM,
          backgroundColor: Colors.black,
        );
      }
    }

    get_image_url_from_uploadPicture(String url) {
      image_url = url;
      return image_url;
    }

    showLoadingWhileSaving(BuildContext context) {
      AlertDialog alert = AlertDialog(
        content: new Row(
          children: [
            CircularProgressIndicator(),
            Container(margin: EdgeInsets.only(left: 5), child: Text("Loading")),
          ],
        ),
      );
      showDialog(
        barrierDismissible: false,
        context: context,
        builder: (BuildContext context) {
          return alert;
        },
      );
    }

    Future _uploadPicture(BuildContext context) async {
      String fileName = basename(_image.path);
      StorageReference storageReference =
          FirebaseStorage.instance.ref().child(fileName);

      StorageUploadTask storageUploadTask = storageReference.putFile(_image);

      showLoadingWhileSaving(context);
      StorageTaskSnapshot storageTaskSnapshot =
          await storageUploadTask.onComplete;

      image_url =
          await (await storageUploadTask.onComplete).ref.getDownloadURL();

      get_image_url_from_uploadPicture(image_url);

      Navigator.pop(context);

      setState(() {
        _showToastMsg("success", "News Successfully Saved!");
      });
    }

    return Scaffold(
      appBar: AppBar(
        leading: Builder(
          builder: (BuildContext context) {
            return IconButton(
              icon: const Icon(null),
              color: Colors.white,
              onPressed: () {},
            );
          },
        ),
        centerTitle: true,
        title: Text(
          "Report a News",
        ),
        backgroundColor: Colors.blueGrey,
      ),
      body: Container(
        child: SingleChildScrollView(
          padding: const EdgeInsets.all(26.0),
          child: Form(
            key: _key,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
                Align(
                    alignment: Alignment.center,
                    child: GFImageOverlay(
                      border: Border.all(color: Colors.blueGrey, width: 4.0),
                      height: 200,
                      width: 200,
                      color: Colors.red,
                      shape: BoxShape.circle,
                      boxFit: BoxFit.fill,
                      image: (widget.imgPath != null)
                          ? _getImage()
                          : AssetImage("images/default_news_image.png"),
                    )),
                SizedBox(
                  height: 30.0,
                ),
                TextFormField(
                  textInputAction: TextInputAction.next,
                  controller: _headlineController,
                  validator: (headline) {
                    if (headline == null || headline.isEmpty) {
                      _showToastMsg("error", "Please enter a Headline");
                    }
                  },
                  decoration: InputDecoration(
                    labelText: "Headline",
                    hintText: "Covid-19 new stats",
                    border: OutlineInputBorder(),
                    icon: Icon(Icons.add_box),
                  ),
                ),
                SizedBox(
                  height: 16.0,
                ),
                TextFormField(
                  maxLines: 5,
                  textInputAction: TextInputAction.next,
                  controller: _descriptionController,
                  validator: (description) {
                    if (description == null || description.isEmpty) {
                      _showToastMsg("error", "Please provide a Headline");
                    }
                  },
                  decoration: InputDecoration(
                    labelText: "Description",
                    hintText: "Covid-19 new stats are sky-rock...",
                    border: OutlineInputBorder(),
                    icon: Icon(Icons.message),
                  ),
                ),
                SizedBox(
                  height: 16.0,
                ),
                DropDownFormField(
                  titleText: 'Priority',
                  value: _dropDownActivity,
                  hintText: 'Select the priority',
                  onSaved: (value) {
                    setState(() {
                      _dropDownActivity = value;
                    });
                  },
                  onChanged: (value) {
                    setState(() {
                      _dropDownActivity = value;
                    });
                  },
                  validator: (value) {
                    if (value == null || value == "") {
                      _showToastMsg("error", "Please select a priority");
                    }
                  },
                  dataSource: [
                    {
                      "display": "High",
                      "value": "High",
                    },
                    {
                      "display": "Medium",
                      "value": "Medium",
                    },
                    {
                      "display": "Low",
                      "value": "Low",
                    },
                  ],
                  textField: 'display',
                  valueField: 'value',
                ),
                SizedBox(
                  height: 16.0,
                ),
                Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Row(
                      children: <Widget>[
                        GFButtonBadge(
                          size: GFSize.SMALL,
                          onPressed: () {
                            _showToastMsg(
                                "other", "Today is : ${formattedDate}");
                          },
                          icon: Icon(
                            Icons.calendar_today,
                            size: 16.0,
                            color: Colors.white,
                          ),
                          text: '',
                        ),
                        SizedBox(
                          width: 10.0,
                        ),
                        Text(
                          "- ${formattedDate}",
                          style: TextStyle(fontSize: 18.0),
                        ),
                      ],
                    ),
                    SizedBox(
                      height: 10.0,
                    ),
                    Row(
                      children: <Widget>[
                        GFButtonBadge(
                          size: GFSize.SMALL,
                          onPressed: () {
                            _showToastMsg("other", "Time is : ${currentTime}");
                          },
                          icon: Icon(
                            Icons.alarm,
                            size: 16.0,
                            color: Colors.white,
                          ),
                          text: '',
                        ),
                        SizedBox(
                          width: 10.0,
                        ),
                        Text(
                          "- ${currentTime}",
                          style: TextStyle(fontSize: 18.0),
                        ),
                      ],
                    ),
                    SizedBox(
                      height: 14.0,
                    ),
                  ],
                ),
                Align(
                  alignment: Alignment.center,
                  child: Text(
                    "Date and time will be saved automaticallt on \"Save\"",
                    textAlign: TextAlign.center,
                    style: TextStyle(
                      color: Colors.grey,
                    ),
                  ),
                ),
                SizedBox(
                  height: 20.0,
                ),
                Row(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    RaisedButton.icon(
                      icon: Icon(Icons.refresh),
                      color: Colors.orange,
                      textColor: Colors.white,
                      label: Text("Retake"),
                      onPressed: () async {
                        Navigator.of(context).pop();
                      },
                    ),
                    RaisedButton.icon(
                      icon: Icon(Icons.add_a_photo),
                      color: Colors.green,
                      textColor: Colors.white,
                      label: Text("Snap"),
                      onPressed: () async {
                        try {
                          // first upload the photo
                          if (_key.currentState.validate()) {
                            _showToastMsg("other",
                                get_image_url_from_uploadPicture("cool"));
                          } else {
                            _showToastMsg("other",
                                get_image_url_from_uploadPicture("empty"));
                          }

                          // await FireStoreServiceApi().add_news(News(
                          //   headline: _headlineController.text,
                          //   description: _descriptionController.text,
                          //   imageUrl: image_url,
                          //   timeNews: currentTime.toString(),
                          //   timeDate: formattedDate.toString(),
                          //   priority: _dropDownActivity.toString(),
                          // ));
                        } catch (e) {
                          print(e);
                        }
                      },
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

告诉我我哪里出了问题以及如何解决

谢谢。

1 个答案:

答案 0 :(得分:1)

无论何时要显示输入错误,都必须在String中返回一个validator

TextFormField(
  textInputAction: TextInputAction.next,
  controller: _headlineController,
  validator: (headline) {
    if (headline == null || headline.isEmpty) {
      return "Please enter a Headline";
    }
    return null;
  },
  decoration: InputDecoration(
    labelText: "Headline",
    hintText: "Covid-19 new stats",
    border: OutlineInputBorder(),
    icon: Icon(Icons.add_box),
  ),
),