我正在使用以下代码创建一个简单的多步骤问答表单,但表单似乎无法保存它们的值,当我转到第二个表单并返回时,
textFormField
值消失了。
“handler.dart”:
class FormCreateHandler extends StatefulWidget {
const FormCreateHandler({super.key});
static const routeName = '/-form-handler';
@override
State<FormCreateHandler> createState() =>
_FormCreateHandlerState();
}
class _FormCreateHandlerState extends State<FormCreateHandler> {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<Create>(
create: (context) => Create(),
child: Consumer<Create>(
builder: (context, modal, child) {
switch (modal.activeIndex) {
case 0:
return const FormQuestion1();
case 1:
return const FormQuestion2();
default:
return const FormQuestion1();
}
},
),
);
}
}
“表格问题1.dart”:
class FormQuestion1 extends StatefulWidget {
const FormQuestion1({super.key});
static const routeName = '/form-question1';
@override
State<FormQuestion1> createState() => _FormQuestion1State();
}
class _FormQuestion1State extends State<FormQuestion1> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Consumer<Create>(builder: (context, modal, child) {
return Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextFormField(
decoration: const InputDecoration(
labelText: 'title',
border: OutlineInputBorder(),
),
validator: (value) {
if (value!.isEmpty)
return 'Please enter the title of question';
},
),
TextFormField(
minLines: 3,
maxLines: 5,
decoration: const InputDecoration(
labelText: 'description',
border: OutlineInputBorder(),
),
validator: (value) {
if (value!.isEmpty || value.length < 30) {
return 'Description must be longer';
}
},
),
Padding(
padding: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
flex: 1,
child: ElevatedButton(
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
_formKey.currentState!.save();
modal.changeStep(2);
}
},
child: Text('Back'),
),
),
Expanded(
flex: 2,
child: ElevatedButton(
onPressed: null,
child: Text('Submit'),
),
),
Expanded(
flex: 1,
child: ElevatedButton(
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
_formKey.currentState!.save();
modal.changeStep(4);
}
},
child: Text('Next'),
),
),
],
),
),
],
),
),
);
});
}
}
“表格问题2.dart”
class FormQuestion2 extends StatefulWidget {
const FormQuestion2({super.key});
static const routeName = '/form-question2';
@override
State<FormQuestion2> createState() => _FormQuestion2State();
}
class _FormQuestion2State extends State<FormQuestion2> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Consumer<Create>(builder: (context, modal, child) {
return Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextFormField(
decoration: const InputDecoration(
labelText: 'title',
border: OutlineInputBorder(),
),
validator: (value) {
if (value!.isEmpty)
return 'Please enter the title of question';
},
),
TextFormField(
minLines: 3,
maxLines: 5,
decoration: const InputDecoration(
labelText: 'description',
border: OutlineInputBorder(),
),
validator: (value) {
if (value!.isEmpty || value.length < 30) {
return 'Description must be longer';
}
},
),
Padding(
padding: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
flex: 1,
child: ElevatedButton(
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
_formKey.currentState!.save();
modal.changeStep(2);
}
},
child: Text('Back'),
),
),
Expanded(
flex: 2,
child: ElevatedButton(
onPressed: null,
child: Text('Submit'),
),
),
Expanded(
flex: 1,
child: ElevatedButton(
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
_formKey.currentState!.save();
modal.changeStep(4);
}
},
child: Text('Next'),
),
),
],
),
),
],
),
),
);
});
}
}
如何修改此代码以保持表单的状态,直到用户按下提交按钮或关闭表单?
我第一次误解你的问题。您的问题是您正在更改消费者中的小部件。要解决此问题,您需要为消费者中的每个案例使用一个 GlobalKeys,例如:
switch (modal.activeIndex) {
case 0:
return const BasicDetails(key: _basicKey);
case 1:
return const EducationDetails(key: _educationKey);
default:
return const BasicDetails(key: _basicKey);
}
,或将数据存储在这些小部件之外(例如,您可以使用 BLoC)并在构建方法中初始化它们
我认为这是由于 ListView 优化,您可以选择错误的方式:在 ListView 上使用 shrinkWrap: true,或者正确的方式:在 TextFormField 上使用 TextEditingController 或 initialValue 和 onChange