Flutter:如何使我的字段成为必填字段并在按下提交按钮后保存我的下拉列表和文本数据?
Flutter: How to make my fields required and save my dropdown and text data after the submit button is pressed?
这是我的代码。我无法保存回复,甚至下拉菜单和文本字段都没有显示所需的文本和 * 符号。我不知道如何保存用户提交的回复以及在哪里保存以及我应该在提交按钮的 on Pressed 函数上写什么以保存其上方所有字段的回复。
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
TextEditingController problemBox = TextEditingController();
List _listItem = ["Category 1", "Category 2", "Category 3", "Category 4"];
List _listItem1 = [
"Sub Category 1",
"Sub Category 2",
"Sub Category 3",
"Sub Category 4"
];
List _listItem2 = ["CRIS", "ADMINISTRATION", "ZONE", "DEPARTMENT"];
String dropdownValue;
String holder = '';
void getDropDownItem() {
setState(() {
holder = dropdownValue;
});
}
String dropdownValue1;
String holder1 = '';
void getDropDownItem1() {
setState(() {
holder1 = dropdownValue1;
});
}
String dropdownValue2;
String holder2 = '';
void getDropDownItem2() {
setState(() {
holder2 = dropdownValue2;
});
}
bool autoValidate = true;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text("Feedback"),
centerTitle: true,
leading: IconButton(
onPressed: () {},
icon: Icon(Icons.home),
),
),
body: Container(
child: Center(
child: SingleChildScrollView(
child: Form(
autovalidateMode: AutovalidateMode.onUserInteraction,
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text("CATEGORY"),
DropdownButton<String>(
hint: Text("Select"),
value: dropdownValue,
items: _listItem
.map<DropdownMenuItem<String>>((valueItem) {
return DropdownMenuItem<String>(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
onChanged: (value) {
setState(() {
dropdownValue = value;
});
},
)
],
),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text("SUBCATEGORY"),
DropdownButton<String>(
hint: Text("Select"),
value: dropdownValue1,
items: _listItem1
.map<DropdownMenuItem<String>>((valueItem1) {
return DropdownMenuItem<String>(
value: valueItem1,
child: Text(valueItem1),
);
}).toList(),
onChanged: (value) {
setState(() {
dropdownValue1 = value;
});
},
)
],
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text("MARKED TO"),
DropdownButton<String>(
hint: Text("Select"),
value: dropdownValue2,
items: _listItem2
.map<DropdownMenuItem<String>>((valueItem2) {
return DropdownMenuItem<String>(
value: valueItem2,
child: Text(valueItem2),
);
}).toList(),
onChanged: (value) {
setState(() {
dropdownValue2 = value;
});
},
)
],
),
SizedBox(height: 10),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.fromLTRB(70, 00, 70, 00),
child: TextFormField(
validator: (String value) {
if (value.isEmpty) {
return "Name is required";
}
return null;
},
controller: problemBox,
decoration: InputDecoration(
hintText: "Describe your problem here.",
),
maxLength: 1000,
maxLines: 5,
),
)
],
),
SizedBox(height: 10),
ButtonTheme(
child: ElevatedButton(
child: Text("Submit"),
onPressed: () {
_formKey.currentState.save();
},
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(
horizontal: 25, vertical: 15),
),
),
),
]),
),
),
)));
}
要显示文本字段的错误,请检查表单是否有效:
ButtonTheme(
child: ElevatedButton(
child: Text("Submit"),
onPressed: () {
if(
_formKey.currentState.validate() // add this
) {
print(" form is valideate"); // here do what you want when the form is validate :)
}
},
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(
horizontal: 25, vertical: 15),
),
),
)
要验证 dropDown ,将 DropdownButton 更改为 DropdownButtonFormField 有一个 属性 验证器 –
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Flexible(child: Text("MARKED TO")),
Flexible(
child: DropdownButtonFormField<String>( // change to DropdownButtonFormField
hint: Text("Select"),
value: dropdownValue2,
validator: (value) => value == null ? 'your message' : null,// add validator property
items: _listItem2
.map<DropdownMenuItem<String>>((valueItem2) {
return DropdownMenuItem<String>(
value: valueItem2,
child: Text(valueItem2),
);
}).toList(),
onChanged: (value) {
setState(() {
dropdownValue2 = value;
});
},
),
)
],
),
对于 * 您可以将其添加到必填字段
例如:
RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: 'MARKED TO',
children: <TextSpan>[
TextSpan(
text: '*',
style: TextStyle(color: Colors.red),
),
],
),
)
这是我的代码。我无法保存回复,甚至下拉菜单和文本字段都没有显示所需的文本和 * 符号。我不知道如何保存用户提交的回复以及在哪里保存以及我应该在提交按钮的 on Pressed 函数上写什么以保存其上方所有字段的回复。
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
TextEditingController problemBox = TextEditingController();
List _listItem = ["Category 1", "Category 2", "Category 3", "Category 4"];
List _listItem1 = [
"Sub Category 1",
"Sub Category 2",
"Sub Category 3",
"Sub Category 4"
];
List _listItem2 = ["CRIS", "ADMINISTRATION", "ZONE", "DEPARTMENT"];
String dropdownValue;
String holder = '';
void getDropDownItem() {
setState(() {
holder = dropdownValue;
});
}
String dropdownValue1;
String holder1 = '';
void getDropDownItem1() {
setState(() {
holder1 = dropdownValue1;
});
}
String dropdownValue2;
String holder2 = '';
void getDropDownItem2() {
setState(() {
holder2 = dropdownValue2;
});
}
bool autoValidate = true;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text("Feedback"),
centerTitle: true,
leading: IconButton(
onPressed: () {},
icon: Icon(Icons.home),
),
),
body: Container(
child: Center(
child: SingleChildScrollView(
child: Form(
autovalidateMode: AutovalidateMode.onUserInteraction,
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text("CATEGORY"),
DropdownButton<String>(
hint: Text("Select"),
value: dropdownValue,
items: _listItem
.map<DropdownMenuItem<String>>((valueItem) {
return DropdownMenuItem<String>(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
onChanged: (value) {
setState(() {
dropdownValue = value;
});
},
)
],
),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text("SUBCATEGORY"),
DropdownButton<String>(
hint: Text("Select"),
value: dropdownValue1,
items: _listItem1
.map<DropdownMenuItem<String>>((valueItem1) {
return DropdownMenuItem<String>(
value: valueItem1,
child: Text(valueItem1),
);
}).toList(),
onChanged: (value) {
setState(() {
dropdownValue1 = value;
});
},
)
],
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text("MARKED TO"),
DropdownButton<String>(
hint: Text("Select"),
value: dropdownValue2,
items: _listItem2
.map<DropdownMenuItem<String>>((valueItem2) {
return DropdownMenuItem<String>(
value: valueItem2,
child: Text(valueItem2),
);
}).toList(),
onChanged: (value) {
setState(() {
dropdownValue2 = value;
});
},
)
],
),
SizedBox(height: 10),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.fromLTRB(70, 00, 70, 00),
child: TextFormField(
validator: (String value) {
if (value.isEmpty) {
return "Name is required";
}
return null;
},
controller: problemBox,
decoration: InputDecoration(
hintText: "Describe your problem here.",
),
maxLength: 1000,
maxLines: 5,
),
)
],
),
SizedBox(height: 10),
ButtonTheme(
child: ElevatedButton(
child: Text("Submit"),
onPressed: () {
_formKey.currentState.save();
},
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(
horizontal: 25, vertical: 15),
),
),
),
]),
),
),
)));
}
要显示文本字段的错误,请检查表单是否有效:
ButtonTheme(
child: ElevatedButton(
child: Text("Submit"),
onPressed: () {
if(
_formKey.currentState.validate() // add this
) {
print(" form is valideate"); // here do what you want when the form is validate :)
}
},
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(
horizontal: 25, vertical: 15),
),
),
)
要验证 dropDown ,将 DropdownButton 更改为 DropdownButtonFormField 有一个 属性 验证器 –
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Flexible(child: Text("MARKED TO")),
Flexible(
child: DropdownButtonFormField<String>( // change to DropdownButtonFormField
hint: Text("Select"),
value: dropdownValue2,
validator: (value) => value == null ? 'your message' : null,// add validator property
items: _listItem2
.map<DropdownMenuItem<String>>((valueItem2) {
return DropdownMenuItem<String>(
value: valueItem2,
child: Text(valueItem2),
);
}).toList(),
onChanged: (value) {
setState(() {
dropdownValue2 = value;
});
},
),
)
],
),
对于 * 您可以将其添加到必填字段
例如:
RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: 'MARKED TO',
children: <TextSpan>[
TextSpan(
text: '*',
style: TextStyle(color: Colors.red),
),
],
),
)