Flutter TypeAhead 小部件验证不起作用

Flutter TypeAhead widget validation is not working

我有一个表单,其中包含三种类型的小部件,例如 DropDownTextFieldTypeAhead。我已经导入了一个名为 flutter_typeahead 的包,它基本上是一个与 TextField 混合的动态 DropDown。(有关 flutter_typeahead 的更多信息:flutter_typeahead,但不需要知道 flutter_typeahead 小部件以便能够理解和解决问题。)

但是,当我尝试验证时,如果 TypeAhead 小部件为空或 null,那么我会向用户抛出错误。到目前为止一切正常。但是,当我填写表单的其他实例(DropDownTextFields)并让 TypeAhead 为空时,验证将不起作用。我的意思是,如果我填写 DropDowns 和 TextFields 并让 TypeAhead 为空,然后尝试提交表单实际提交它。但是,如果我让 TextField 为空或 DropDown 作为默认值,验证工作正常。

综上所述,当所有表单小部件为空时,TypeAhead 验证有效,只有 TypeAhead 为空时无效。

表单小部件

Form formWidget(Map<String, dynamic> map) {
    return Form(
      key: _formKey,
      child: ListView(
        shrinkWrap: true,
        children: [
          customTypeAhead(map['stajTuru'], _stajTuruController,
              _selectedStajTuru, 'Staj Türü'),  //Custom typeahead widget
          customTypeAhead(
              map['doktor'], _doktorController, _selectedDoktor, 'Doktor'), //Custom typeahead widget
          customDropDown(
              _valueOrtam, map['ortam'], hintTextOrtam, onChangedOrtam),
          customDropDown(
              _valueKapsam, map['kapsam'], hintTextKapsam, onChangedKapsam),
          customDropDown(_valueEtkilesim, map['etkilesim'], hintTextEtkilesim,
              onChangedEtkilesim),
          customDropDown(_valueCinsiyet, map['cinsiyet'], hintTextCinsiyet,
              onChangedCinsiyet),
          const SizedBox(
            height: 20,
          ),
          customTextField(
              1, "Kayıt No ", 10, _formData.setKayitNo, isEmpty, _kayit, 80),
          customTextField(
              1, "Hastanın Yaşı", 3, _formData.setYas, isNumeric, _yas, 80),
          customTextField(
              1, "Şikayet", 10, _formData.setSikayet, isEmpty, _sikayet, 80),
          customTextField(1, "Ayırıcı Tanı", 10, _formData.setAyiriciTani,
              isEmpty, _ayirici, 80),
          customTextField(5, "Kesin Tanı", 50, _formData.setKesinTani, isEmpty,
              _kesin, 130),
          customTextField(5, "Tedavi Yöntemi", 200, _formData.setTedaviYontemi,
              isEmpty, _tedavi, 130),
        ],
      ),
    );
  }

customTypeAhead

Widget customTypeAhead(List<String> listItems, TextEditingController controller,
     String? stajTuru,String labelText) {
  //check if the typed item is in the list
  List<String> getSuggestions(String query) {
    return List.of(listItems).where((item) {
      final queryLower = query.toLowerCase();
      final itemLower = item.toLowerCase();
      return itemLower.contains(queryLower);
    }).toList();
  }

  return Padding(
    padding: const EdgeInsets.all(PADDING_VALUE),
    child: Column(
      children: [
        Text(
          labelText,
          style: TEXT_STYLE,
        ),
        TypeAheadFormField<String?>(
          onSuggestionSelected: (String? val) =>controller.text = val!,
          itemBuilder: (context, String? suggestion) {
            return ListTile(
              title: Text(suggestion!),
            );
          },
          suggestionsCallback: getSuggestions,
          validator: (value) {  // This is my validation method
            bool isInTheList=false;
            for(var item in listItems){
              if(item==value) {
                isInTheList=true;
              }
            }
            if (value == null || value.isEmpty || isInTheList==false) {
              return 'Lütfen ${labelText.toLowerCase()} seçiniz';
            } else {
              print("null returned");
              return null;
            }
          },
          textFieldConfiguration: TextFieldConfiguration(
              controller: controller,
              decoration: const InputDecoration(
                  focusedBorder: OutlineInputBorder(
                    borderSide: BorderSide(
                      color: TEXT_COLOR,
                    ),
                  ),
                  border: OutlineInputBorder(
                      borderSide: BorderSide(
                    color: TEXT_COLOR,
                  )))),
        ),
      ],
    ),
  );
} 

提交函数

void formIlet() async {

    if (formArguments != null) {
      if (_formKey.currentState!.validate()) {
        setFormArgumentState();
        bool res = await _mySqlHelper.insertData(formArguments!.formData);
        if (res) {
          _helper.update(formArguments!.formData);
          customSnackBar(context, 'Başarıyla gönderildi');
        } else {
          errorAlert(context);
        }
      }
    } else {
      if (_formKey.currentState!.validate()) {
        setFormDataState();
        isLoading = true;
        bool res = await _mySqlHelper.insertData(_formData).then((val) {
          setState(() {
            isLoading = false;
            _formKey.currentState?.dispose();
          });
          return val;
        });
        if (res) {
          customSnackBar(context, 'Başarıyla gönderildi');
        } else {
          errorAlert(context);
        }
      }
    }
  }

我已经解决了这个问题。我不知道为什么会这样,但是在 Form 中使用 ListView 并不是一个好主意。这就是问题所在。所以,我用 Column 改变了 ListView 并用 SingleChildScrollView 包裹它,问题就解决了。