Flutter如何连续显示未知数量的对话框?

问题描述 投票:0回答:2

我想做的是向用户展示一个由

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'),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

不知道怎么修改才能达到我想要的效果

flutter forms dialog provider state-management
2个回答
1
投票

您可以通过以下方式循环对话框并保存结果。

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);
}


1
投票

使用 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';
    },
  ),
© www.soinside.com 2019 - 2024. All rights reserved.