Flutter调查问卷插件flutter_survey的使用

发布于 1周前 作者 htzhanglong 来自 Flutter

Flutter调查问卷插件flutter_survey的使用

Flutter Survey Logo
Pub License: MIT style: flutter lints License: MIT

Flutter Survey

Screenrecorder-2021-05-11-20-23-21-153

特性

  • ✔️ 消除调查表单中的样板代码。
  • ✔️ 实现条件选择/单选/多选问题。
  • ✔️ 直观地构建自己的问题,支持无限嵌套。
  • ✔️ 可通过builder方法自定义表单组件。
  • ✔️ 可为自定义组件添加属性。
  • ✔️ 支持使用Form小部件进行验证。
  • ✔️ 隐式支持深色主题。

下次更新

  • ✔️ 支持国际化。
  • ✔️ 支持自定义正则表达式验证。
  • ✔️ 支持各种输入格式(如日期选择器、文件上传、滑块等)。
  • ✔️ 跟踪进度。

安装

本项目需要最新的Dart版本。你可以下载最新的Dart版本这里

1. 添加依赖

在你的项目的pubspec.yaml文件中添加以下内容:

dependencies:
    flutter_survey: '^1.0.1'
2. 安装依赖

你可以通过命令行安装包:

$ pub get
..

你也可以通过编辑器来安装,具体请查阅你的编辑器文档。

3. 导入包

在你的Dart代码中导入:

import 'package:flutter_survey/survey.dart';

使用

首先,你需要初始化问题结构,指定问题类型及其可能的答案。你还可以嵌套问题以形成条件问题。这可以通过从服务器获取的JSON格式或通过此包提供的[Question]模型来构造。结构是直观的,并决定了表单的流程。

问题类型

问题根据其接受的输入类型分类。

文本输入问题

顾名思义,这里的答案不限于特定的选择。用户可以输入单行或多行文本。将answerChoice变量设置为null或完全省略它会给你这种效果。

Question(
 question: "What is your name?",
)
单选问题

在这里,使用单选按钮作为输入。你需要定义可能的答案选择作为一个Map,其中键是答案选项。注意,相应键的值为null,因为它们没有关联的问题列表。

Question(
  question: 'Do you like drinking coffee?',
  answerChoices: {
    "Yes": null,
    "No": null,
  },
)
多选问题

在这里,使用复选框作为输入。就像单选问题一样,你需要定义可能的答案选择作为一个Map,其中键是答案选项。即使在这里,相应的键的值也为null,原因与单选问题相同。不同之处在于,你需要将isSingleChoice设置为false。

Question(
  isSingleChoice: false,
  question: 'What are the brands that you have tried?',
  answerChoices: {
    "Nestle": null,
    "Starbucks": null,
    "Coffee Day": null,
  },
)
条件/嵌套问题

在这里,你可以定义基于前一个问题答案的问题。answerChoices字段中定义的键的值决定了流程。例如,如果用户选择“是”,那么用户会被问到“你尝试过哪些品牌?”等问题。

Question(
  isMandatory: true,
  question: 'Do you like drinking coffee?',
  answerChoices: {
    "Yes": [
      Question(
          singleChoice: false,
          question: "What are the brands that you've tried?",
          answerChoices: {
            "Nestle": null,
            "Starbucks": null,
            "Coffee Day": [
              Question(
                question: "Did you enjoy visiting Coffee Day?",
                isMandatory: true,
                answerChoices: {
                  "Yes": [
                    Question(
                      question: "Please tell us why you like it",
                    )
                  ],
                  "No": [
                    Question(
                      question: "Please tell us what went wrong",
                    )
                  ],
                },
              )
            ],
          })
    ],
    "No": [
      Question(
        question: "Do you like drinking Tea then?",
        answerChoices: {
          "Yes": [
            Question(
                question: "What are the brands that you've tried?",
                answerChoices: {
                  "Nestle": null,
                  "ChaiBucks": null,
                  "Indian Premium Tea": [
                    Question(
                      question: "Did you enjoy visiting IPT?",
                      answerChoices: {
                        "Yes": [
                          Question(
                            question: "Please tell us why you like it",
                          )
                        ],
                        "No": [
                          Question(
                            question: "Please tell us what went wrong",
                          )
                        ],
                      },
                    )
                  ],
                })
          ],
          "No": null,
        },
      )
    ],
  },
)
全部问题结构表示为一个List
List<Question> _initialData = [
  Question(
    isMandatory: true,
    question: 'Do you like drinking coffee?',
    answerChoices: {
      "Yes": [
        Question(
            singleChoice: false,
            question: "What are the brands that you've tried?",
            answerChoices: {
              "Nestle": null,
              "Starbucks": null,
              "Coffee Day": [
                Question(
                  question: "Did you enjoy visiting Coffee Day?",
                  isMandatory: true,
                  answerChoices: {
                    "Yes": [
                      Question(
                        question: "Please tell us why you like it",
                      )
                    ],
                    "No": [
                      Question(
                        question: "Please tell us what went wrong",
                      )
                    ],
                  },
                )
              ],
            })
      ],
      "No": [
        Question(
          question: "Do you like drinking Tea then?",
          answerChoices: {
            "Yes": [
              Question(
                  question: "What are the brands that you've tried?",
                  answerChoices: {
                    "Nestle": null,
                    "ChaiBucks": null,
                    "Indian Premium Tea": [
                      Question(
                        question: "Did you enjoy visiting IPT?",
                        answerChoices: {
                          "Yes": [
                            Question(
                              question: "Please tell us why you like it",
                            )
                          ],
                          "No": [
                            Question(
                              question: "Please tell us what went wrong",
                            )
                          ],
                        },
                      )
                    ],
                  })
            ],
            "No": null,
          },
        )
      ],
    },
  ),
  Question(
      question: "What age group do you fall in?",
      isMandatory: true,
      answerChoices: const {
        "18-20": null,
        "20-30": null,
        "Greater than 30": null,
      })
];
将问题列表传递给ConditionalQuestions小部件

这是处理表单的主要小部件。上述构造的问题列表被传递给initialData参数。onNext回调函数是一个可选参数,当调用时会传递当前调查的状态,即一个QuestionResult对象的列表。

Survey(
  initialData: _initialData,
  onNext:(questionResults){
      print(questionResults);
      // 存储结果
  },
)

贡献

帮助使这个包更实用并满足社区需求,可以通过报告错误、提交反馈或打开PR来实现。

关于我

访问我的LinkedIn 这里


示例代码

import 'package:flutter/material.dart';
import 'package:flutter_survey/flutter_survey.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Survey Demo',
      theme: ThemeData(
        brightness: Brightness.light,
      ),
      darkTheme: ThemeData(
        brightness: Brightness.dark,
      ),
      themeMode: ThemeMode.system,
      home: const MyHomePage(title: 'Flutter Survey'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _formKey = GlobalKey<FormState>();
  List<QuestionResult> _questionResults = [];
  final List<Question> _initialData = [
    Question(
      isMandatory: true,
      question: "Please tell us why you like it",
    ),
    Question(
      isMandatory: true,
      question: 'Do you like drinking coffee?',
      answerChoices: {
        "Yes": [
          Question(
              singleChoice: false,
              question: "What are the brands that you've tried?",
              answerChoices: {
                "Nestle": null,
                "Starbucks": null,
                "Coffee Day": [
                  Question(
                    question: "Did you enjoy visiting Coffee Day?",
                    isMandatory: true,
                    answerChoices: {
                      "Yes": [
                        Question(
                          question: "Please tell us why you like it",
                        )
                      ],
                      "No": [
                        Question(
                          question: "Please tell us what went wrong",
                        )
                      ],
                    },
                  )
                ],
              })
        ],
        "No": [
          Question(
            question: "Do you like drinking Tea then?",
            answerChoices: {
              "Yes": [
                Question(
                    question: "What are the brands that you've tried?",
                    answerChoices: {
                      "Nestle": null,
                      "ChaiBucks": null,
                      "Indian Premium Tea": [
                        Question(
                          question: "Did you enjoy visiting IPT?",
                          answerChoices: {
                            "Yes": [
                              Question(
                                question: "Please tell us why you like it",
                              )
                            ],
                            "No": [
                              Question(
                                question: "Please tell us what went wrong",
                              )
                            ],
                          },
                        )
                      ],
                    })
              ],
              "No": null,
            },
          )
        ],
      },
    ),
    Question(
        question: "What age group do you fall in?",
        isMandatory: true,
        answerChoices: const {
          "18-20": null,
          "20-30": null,
          "Greater than 30": null,
        })
  ];

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Form(
        key: _formKey,
        child: Survey(
            onNext: (questionResults) {
              _questionResults = questionResults;
            },
            initialData: _initialData),
      ),
      bottomNavigationBar: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          SizedBox(
            width: double.infinity,
            height: 56,
            child: TextButton(
              style: TextButton.styleFrom(
                foregroundColor: Colors.white,
                backgroundColor: Colors.cyanAccent, // 背景颜色
              ),
              child: const Text("Validate"),
              onPressed: () {
                if (_formKey.currentState!.validate()) {
                  // 执行一些操作
                }
              },
            ),
          ),
        ],
      ),
    );
  }
}

更多关于Flutter调查问卷插件flutter_survey的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter调查问卷插件flutter_survey的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用flutter_survey插件来创建一个简单的调查问卷的示例代码。

首先,确保你已经在pubspec.yaml文件中添加了flutter_survey依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_survey: ^最新版本号  # 请替换为实际的最新版本号

然后运行flutter pub get来获取依赖。

接下来,你可以在你的Flutter应用中创建一个调查问卷。以下是一个简单的示例:

import 'package:flutter/material.dart';
import 'package:flutter_survey/flutter_survey.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Survey Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SurveyPage(),
    );
  }
}

class SurveyPage extends StatefulWidget {
  @override
  _SurveyPageState createState() => _SurveyPageState();
}

class _SurveyPageState extends State<SurveyPage> {
  final List<SurveyQuestionModel> questions = [
    SurveyQuestionModel(
      questionTitle: "What is your age?",
      questionType: SurveyQuestionType.text,
      isRequired: true,
    ),
    SurveyQuestionModel(
      questionTitle: "Which of the following do you prefer?",
      questionType: SurveyQuestionType.checkbox,
      options: [
        SurveyOptionModel(title: "Apple"),
        SurveyOptionModel(title: "Banana"),
        SurveyOptionModel(title: "Cherry"),
      ],
      isRequired: true,
      multiSelect: true,
    ),
    SurveyQuestionModel(
      questionTitle: "How satisfied are you with our service?",
      questionType: SurveyQuestionType.rating,
      isRequired: true,
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Survey'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: SurveyWidget(
          questions: questions,
          onSubmit: (results) {
            // 处理调查结果
            print("Survey Results: $results");
            Navigator.of(context).push(
              MaterialPageRoute(
                builder: (context) => ResultPage(results: results),
              ),
            );
          },
        ),
      ),
    );
  }
}

class ResultPage extends StatelessWidget {
  final Map<String, dynamic> results;

  ResultPage({required this.results});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Survey Results'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: ListView.builder(
          itemCount: results.keys.length,
          itemBuilder: (context, index) {
            final key = results.keys.elementAt(index);
            final value = results[key];
            return ListTile(
              title: Text("$key: $value"),
            );
          },
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个包含三个问题的调查问卷:

  1. 一个文本输入框问题。
  2. 一个多选复选框问题。
  3. 一个评分问题。

SurveyWidget用于显示调查问卷,并在用户提交时调用onSubmit回调函数。在回调函数中,我们打印调查结果并导航到一个新页面来显示结果。

注意:

  • 请确保你使用的flutter_survey插件版本与示例代码兼容。
  • 根据需要调整问卷问题和选项。

希望这个示例能帮助你快速上手flutter_survey插件!

回到顶部