如何在下拉列表中添加验证器
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了解更多信息
我是 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了解更多信息