如何在下拉列表中添加验证器

How to add validator in drop down In flutter

我是 Flutter 的新手,我在记录字段中使用下拉菜单,但我想如果用户没有填写下拉菜单并且用户单击保存按钮,它将显示“请填写下拉菜单”,但在代码中,我试图添加“验证器”,但它显示“未定义命名参数 'validator'”。谁能知道如何解决这个问题?请帮忙。谢谢

String selectExpense;

class RecordExpense extends StatefulWidget {
  @override
  _RecordExpenseState createState() => _RecordExpenseState();
}

class _RecordExpenseState extends State<RecordExpense> {
  //DatabaseReference _ref;
  final date = TextEditingController();
  final currency = TextEditingController();
  final category = TextEditingController();
  final amount = TextEditingController();
  final description = TextEditingController();
  final FirebaseAuth _auth = FirebaseAuth.instance;
  final databaseReference = FirebaseFirestore.instance;
  GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  String _email, _password;

  Future<String> getCurrentUID() async {
    Future.value(FirebaseAuth.instance.currentUser);
    //return uid;
  }

  @override

  String selectCurrency;

  final expenseSelected = TextEditingController();
  final currencySelected = TextEditingController();



  List <String> expensecategories = [
    "Food",
    "Social Life",
    "Transportation",
    "Beauty",
    "Household",
    "Education",
    "Health",
    "Gift",
    "Other"
  ];

  List <String> currencycategories = [
    "IDR",
    "MYR",
    "USD",
    "CNY"
  ];


  DateTime _selectedDate;

  void initState(){
    //_ref = FirebaseDatabase.instance.reference().child('Transaction');
  }

  Widget build(BuildContext context) {
    //FirebaseFirestore firestore = FirebaseFirestore.instance;
    //CollectionReference collect= firestore.collection("TransactionExpense");


    final FirebaseAuth _auth = FirebaseAuth.instance;
    final User user =_auth.currentUser;
    final uid = user.uid;


    String dates;
    String amounts;
    String selectExpenses;
    String descriptions;
    return new Form(
      child: SingleChildScrollView(
        child: Padding(
          padding: EdgeInsets.all(20.0),

          child: Container(
            child: Form(
              key: _formKey,
              child: Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: <Widget>[
                    Container(
                      child: TextFormField(
                        validator: (input) {
                          if (input.isEmpty) return 'Please fill up the text fields';
                        },
                        cursorColor: Colors.grey,
                        controller: date,
                        onTap: () {
                          _selectDate(context);
                        },
                        decoration: InputDecoration(
                          labelText: getTranslated((context), "date_text"),
                          labelStyle: TextStyle(
                              fontSize: 18.0, color: Colors.black),
                          hintText: getTranslated((context), "date_hint"),
                          enabledBorder: UnderlineInputBorder(

                            borderSide: BorderSide(color: secondary),
                          ),
                          focusedBorder: UnderlineInputBorder(
                            borderSide: BorderSide(color: secondary),
                          ),
                        ),
                      ),
                    ),
                    SizedBox(height: 20),
                    Row(
                      children: <Widget> [
                        new Expanded(child: new DropDownField(
                          controller: currencySelected,
                          labelText: getTranslated((context), "currency_hint"),
                          enabled: true,
                          itemsVisibleInDropdown: 4,
                          items: currencycategories,
                          onValueChanged: (dynamic value) {
                            selectCurrency = value;
                          },
                          value: selectCurrency,
                          required: false,
                        ),
                          flex: 2,
                        ),
                        new SizedBox(
                          width: 10.0,
                        ),
                        new Expanded(child:
                        TextFormField(
                          validator: (input) {
                            if (input.isEmpty) return 'Please fill up the text fields';
                          },
                          cursorColor: Colors.grey,
                          controller: amount,
                          decoration: InputDecoration(
                            labelText: getTranslated((context), "amount_text"),
                            labelStyle: TextStyle(
                                fontSize: 18.0, color: Colors.black),
                            hintText: getTranslated((context), "amount_text"),
                            enabledBorder: UnderlineInputBorder(

                              borderSide: BorderSide(color: secondary),
                            ),
                            focusedBorder: UnderlineInputBorder(
                              borderSide: BorderSide(color: secondary),
                            ),
                          ),
                          keyboardType: TextInputType.number,
                        ),)

                      ],
                    ),
                    Container(
                      padding: EdgeInsets.only(top: 20.0),
                      child: Container(
                        decoration: BoxDecoration(
                          border: Border.all(color: secondary),
                          borderRadius: BorderRadius.circular(15.0),
                        ),
                        child: DropDownField(
                          controller: expenseSelected,
                          hintText: getTranslated((context), "category_hint"),
                          labelText: getTranslated((context), "category_text"),
                          enabled: true,
                          itemsVisibleInDropdown: 4,
                          items: expensecategories,
                          onValueChanged: (dynamic value) {
                            selectExpense = value;
                          },
                          value: selectExpense,
                          required: false,
                        ),
                      ),
                    ),

                    SizedBox(height: 20),
                    Container(
                      //padding: EdgeInsets.all(20),
                      child: TextFormField(
                        validator: (input) {
                          if (input.isEmpty) return 'Please fill up the text fields';
                        },
                        cursorColor: Colors.grey,
                        controller: description,
                        maxLines: 2,
                        decoration: InputDecoration(
                          labelText: getTranslated((context), "description_text"),
                          labelStyle: TextStyle(
                              fontSize: 18.0, color: Colors.black),
                          hintText: getTranslated((context), "description_expense"),
                          enabledBorder: UnderlineInputBorder(

                            borderSide: BorderSide(color: secondary),
                          ),
                          focusedBorder: UnderlineInputBorder(
                            borderSide: BorderSide(color: secondary),
                          ),
                        ),
                      ),
                    ),
                    Container(
                        padding: EdgeInsets.only(
                            top: 25.0, left: 20.0, right: 20.0),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            Expanded(
                              child: ElevatedButton(

                                onPressed: () async {
                                  if(!_formKey.currentState.validate()){
                                    return;
                                  }
                                  _formKey.currentState.save();
                                  await FirebaseFirestore.instance.collection('users').doc(userID).collection('TransactionExpense').add({
                                        'date': date.text,
                                        'currency': selectCurrency,
                                        'amount': amount.text,
                                        'category': selectExpense,
                                        'description': description.text,
                                      });
                                      date.text = "";
                                      amount.text = "";
                                      description.text = "";


                                  /*
                                UserCredential _user =
                                    await FirebaseAuth.instance.signInWithEmailAndPassword(email: _email, password: _password);
                                String _uid = _user.user.uid;

                                 */

                                  //await FirebaseFirestore.instance.collection('TransactionExpense').doc(_uid).set({

/*
                            final FirebaseAuth _auth = FirebaseAuth
                                .instance;
                            final User user = _auth.currentUser;
                            final uid = user.uid;

                            await DatabaseService().updateData(
                                uid, date.text, amount.text,
                                selectExpense, description.text);
                            Navigator.pop(context);
                            */
                                },
                                child: Text(
                                    getTranslated((context), "save_button").toUpperCase(), style: TextStyle(
                                  fontSize: 14,
                                )),
                                style: ButtonStyle(
                                  padding: MaterialStateProperty.all<
                                      EdgeInsets>(EdgeInsets.all(15)),
                                  foregroundColor: MaterialStateProperty
                                      .all<Color>(Colors.white),
                                  backgroundColor: MaterialStateProperty
                                      .all<Color>(Colors.pink),
                                  shape: MaterialStateProperty.all<
                                      RoundedRectangleBorder>(
                                    RoundedRectangleBorder(
                                        borderRadius: BorderRadius.circular(
                                            15.0),
                                        side: BorderSide(color: secondary)
                                    ),
                                  ),
                                ),

                              ),
                            ),
                            SizedBox(width: 20, height: 10),
                            Expanded(
                              child: ElevatedButton(
                                onPressed: () {
                                  clearButton();
                                },
                                child: Text(
                                    getTranslated((context), "clear_button").toUpperCase(), style: TextStyle(
                                    fontSize: 14
                                )),
                                style: ButtonStyle(
                                  padding: MaterialStateProperty.all<
                                      EdgeInsets>(EdgeInsets.all(15)),
                                  foregroundColor: MaterialStateProperty
                                      .all<Color>(Colors.white),
                                  backgroundColor: MaterialStateProperty
                                      .all<Color>(Colors.pink),
                                  shape: MaterialStateProperty.all<
                                      RoundedRectangleBorder>(
                                    RoundedRectangleBorder(
                                        borderRadius: BorderRadius.circular(
                                            15.0),
                                        side: BorderSide(color: secondary)
                                    ),
                                  ),
                                ),
                              ),
                            )
                          ],
                        )
                    ),
                  ],
                ),
              ),
            ),
          )
        ),
      );
  }

  void clearButton(){
    date.clear();
    amount.clear();
    category.clear();
    description.clear();
  }
  _selectDate(BuildContext context) async {
    DateTime newSelectedDate = await showDatePicker(
        context: context,
        initialDate: _selectedDate != null ? _selectedDate : DateTime.now(),
        firstDate: DateTime(2000),
        lastDate: DateTime(2040),
        builder: (BuildContext context, Widget child) {
          return Theme(
            data: ThemeData.dark().copyWith(
              colorScheme: ColorScheme.dark(
                primary: secondary,
                onPrimary: Colors.black,
                surface: primary,
                onSurface: Colors.white,
              ),
              dialogBackgroundColor: Colors.black,
            ),
            child: child,
          );
        });

    if (newSelectedDate != null) {
      _selectedDate = newSelectedDate;
      date
        ..text = DateFormat.yMMMd().format(_selectedDate)
        ..selection = TextSelection.fromPosition(TextPosition(
            offset: date.text.length,
            affinity: TextAffinity.upstream));
    }
  }
}
class AlwaysDisabledFocusNode extends FocusNode {
  @override
  bool get hasFocus => false;
}

validator参数仅在FormField上可用类,这些类在flutter sdk中以FormForm Field结尾。

要使其正常工作,您应该将 DropDownButton 替换为 DropDownButtonFormField 小部件以访问验证器。

查看docs了解更多信息