我想做的是向用户展示一个由
Dialog
组成的Form
,然后用户填写2个TextFormFields
并点击下一步ElevatedButton
。然后将出现另一个类似的Dialog/form
,用户可以做同样的事情,直到他想完成并按提交ElevatedButton
(即一个用户可能想要添加3个问题/答案,另一个用户可能想要添加10个)。此外,用户可以单击返回ElevatedButton
并查看以前的Dialog/Form
s。
T 有以下代码,但它不起作用,因为它不能保持以前的表单状态,也不能提交表单:
class _FormQuestionsState extends State<FormQuestions> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
children: [
TextFormField(
decoration: const InputDecoration(
labelText: 'Queation',
border: OutlineInputBorder(),
),
validator: (value) {
if (value!.isEmpty) return 'Please enter the title of the question';
},
),
TextFormField(
minLines: 3,
maxLines: 5,
decoration: const InputDecoration(
labelText: 'Answer',
border: OutlineInputBorder(),
),
validator: (value) {
if (value!.isEmpty || value.length < 30) {
return 'Answer must be longer';
}
},
),
Padding(
padding: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
flex: 1,
child: ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
showDialog(
context: context,
builder: (context) =>
const Dialog(child: FormQuestions()));
},
child: Text('Back'),
),
),
Expanded(
flex: 2,
child: ElevatedButton(
onPressed: null, // This function should save all the information has been already put on all the forms!
child: Text('Submit'),
),
),
Expanded(
flex: 1,
child: ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
showDialog(
context: context,
builder: (context) =>
const Dialog(child: FormQuestions()));
},
child: Text('Next'),
),
),
],
),
),
],
),
),
);
}
}
不知道怎么修改才能达到我想要的效果
您可以通过以下方式循环对话框并保存结果。
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Demo',
debugShowCheckedModeBanner: false,
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: TextButton(
child: const Text('Show Form'),
onPressed: () => _showForm(context),
),
),
);
}
void _showForm(BuildContext context) async {
final questionAnswers = <QuestionAnswer>[];
var showNextQuestion = true;
while (showNextQuestion) {
final formKey = GlobalKey<FormState>();
final returnValue = await showDialog<bool?>(
context: context,
useRootNavigator: false,
builder: (context) {
String? question, answer;
return SimpleDialog(
children: [
Form(
key: formKey,
child: Column(
children: [
TextFormField(
decoration: const InputDecoration(
labelText: 'Question',
border: OutlineInputBorder(),
),
validator: (value) {
if (value!.isEmpty) {
return 'Please enter the title of the question';
}
return null;
},
onSaved: (value) => question = value,
),
TextFormField(
minLines: 3,
maxLines: 5,
decoration: const InputDecoration(
labelText: 'Answer',
border: OutlineInputBorder(),
),
validator: (value) {
if (value!.isEmpty || value.length > 30) {
return 'Answer must be longer';
}
return null;
},
onSaved: (value) => answer = value,
),
Padding(
padding: const EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
flex: 1,
child: ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('Back'),
),
),
Expanded(
flex: 2,
child: ElevatedButton(
onPressed: () {
if (formKey.currentState!.validate()) {
formKey.currentState?.save();
questionAnswers.add(
QuestionAnswer(question!, answer!));
Navigator.of(context).pop(false);
}
}, // This function should save all the information has been already put on all the forms!
child: const Text('Submit'),
),
),
Expanded(
flex: 1,
child: ElevatedButton(
onPressed: () {
if (formKey.currentState!.validate()) {
formKey.currentState?.save();
questionAnswers.add(
QuestionAnswer(question!, answer!));
Navigator.of(context).pop();
}
},
child: const Text('Next'),
),
),
],
),
),
],
),
),
],
);
});
showNextQuestion = returnValue ?? showNextQuestion;
}
if (context.mounted) {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return Scaffold(
appBar: AppBar(),
body: ListView.builder(
itemBuilder: (context, index) {
final item = questionAnswers[index];
return ListTile(
title: Text(item.question),
subtitle: Text(item.answer),
);
},
itemCount: questionAnswers.length,
),
);
}));
}
}
}
@immutable
class QuestionAnswer {
final String question;
final String answer;
const QuestionAnswer(this.question, this.answer);
}
使用 TextEditingController(), 使用一些独特的字符串或索引作为问题/答案的关键
Map<String, TextEditingController> inputcontroller = {};
inputcontroller["question1"] = TextEditingController();
TextFormField(
controller: inputcontroller["question1"],
decoration: const InputDecoration(
labelText: 'Question',
border: OutlineInputBorder(),
),
validator: (value) {
if (value!.isEmpty) return 'Please enter the title of the question';
},
),