SurveyKit: 用 Flutter 创建精美的调查问卷 (灵感来源于 iOS ResearchKit Surveys)

您是否想显示一份问卷来收集用户意见?医疗试验的调查?一系列说明手册式的指令?SurveyKit 是一个 Flutter 库,可以让您创建这些内容。

在主题上,它旨在提供专业的调研体验。该库力求视觉上干净、精炼且易于配置。我们的目标是让功能尽可能接近 iOS ResearchKit Surveys。我们还为原生 Android 开发者创建了 SurveyKit 版本,在此查看

这是一个早期版本,仍在开发中。请随时通过 issue 提供反馈、想法或改进建议。

示例

流程

屏幕截图

SurveyKit 为您提供的功能

  • 简化调查问卷的创建
  • 开箱即用提供丰富的动画和过渡效果(计划加入自定义动画)
  • 采用一致、精炼、简洁的风格,适合研究目的
  • 调查问卷的导航可以是线性的,也可以基于决策树(有向图)
  • 收集结果并以方便的方式提供给开发者以供进一步使用
  • 赋予您完全自由来创建自己的问题
  • 允许您自定义样式
  • 提供与 iOS ResearchKit Surveys 非常相似的 API 和结构

SurveyKit 目前尚未提供的功能

如前所述,这是一个早期版本,仍在开发中。我们的目标是扩展此库,使其功能与 iOS ResearchKit Surveys 相匹配。

? 设置

要使用此插件,请将 `flutter_surveykit` 添加到您的 `pubspec.yaml` 文件中作为依赖项。

1. 添加依赖项

pubspec.yaml

dependencies:
  surveykit: ^0.1

2. 安装它

flutter pub get

3. 导入它

import 'package:survey_kit/survey_kit.dart';

? 用法

示例

一个可运行的示例项目可以在 这里 找到

创建调查步骤

要创建步骤,请创建这 3 个类之一的实例

InstructionStep

InstructionStep(
    title: 'Your journey starts here',
    text: 'Have fun with a quick survey',
    buttonText: 'Start survey',
);

`title` 是您要进行的调查的通用标题。`text` 在这种情况下,是介绍文本,应提供关于调查内容的简介。`buttonText` 指定启动调查的按钮文本。所有这些属性都必须是资源 ID。

CompletionStep

CompletionStep(
    title: 'You are done',
    text: 'You have finished !!!',
    buttonText: 'Submit survey',
);

`title` 是您要进行的调查的通用标题,与 `InstructionStep` 相同。`text` 在这里应该是激励性的:说明调查已成功完成。`buttonText` 指定结束调查的按钮文本。所有这些属性都必须是资源 ID。

QuestionStep

QuestionStep(
    title: 'Sample title',
    text: 'Sample text',
    answerFormat: TextAnswerFormat(
        maxLines: 5,
    ),
);

`title` 与 `InstructionStep` 和 `CompletionStep` 相同。`text` 是您实际要问的问题。根据此问题的答案类型,您应该设置下一个属性。`answerFormat` 指定您要提问的问题类型(问题的答案类型)。目前支持以下类型

  • TextAnswerFormat
  • IntegerAnswerFormat
  • ScaleAnswerFormat
  • SingleChoiceAnswerFormat
  • MultipleChoiceAnswerFormat
  • BooleanAnswerFormat

剩下要做的就是将您的步骤收集到一个列表中,或将它们内联添加到小部件中。

var steps = [step1, step2, step3, ...]

创建一个任务

接下来您需要一个任务。每个调查问卷 **正好有一个** 任务。`Task` 用于定义用户应如何通过您的 `steps` 进行导航。

OrderedTask

var task = OrderedTask(steps: steps)

`OrderedTask` 仅按给定的顺序显示问题。

NavigableOrderedTask

var task = NavigableOrderedTask(steps: steps)

`NavigableOrderedTask` 允许您指定导航规则。有两种导航规则

通过 `DirectStepNavigationRule`,您可以指定在此步骤之后应跟另一个指定步骤。

task.addNavigationRule(
  forTriggerStepIdentifier: steps[4].id,
  navigationRule: DirectStepNavigationRule(
      destinationStepStepIdentifier: steps[6].id
  ),
);

通过 `MultipleDirectionStepNavigationRule`,您可以根据步骤的答案来指定下一步。

task.addNavigationRule(
  forTriggerStepIdentifier: task.steps[6].id,
  navigationRule: ConditionalNavigationRule(
    resultToStepIdentifierMapper: (input) {
      switch (input) {
        case "Yes":
          return task.steps[0].id;
        case "No":
          return task.steps[7].id;
        default:
          return null;
      }
    },
  ),
);

评估结果

调查完成后,您会收到一个回调。无论 `FinishReason` 是什么,您始终会获得迄今为止收集到的所有结果。`SurveyResult` 包含一个 `StepResult` 列表和 `FinishReason`。`StepResult` 包含一个 `QuestionResult` 列表。

 SurveyKit(
    onResult: (SurveyResult result) {
      //Read finish reason from result (result.finishReason)
      //and evaluate the results
    },
)

风格

Android 和 IOS 已经实现了许多自适应元素。未来还会适配其他部分。可以通过 Flutter 内置主题调整样式。

textTheme 用于
headline2 问题标题
headline5 问题文本
bodyText2 ListTiles 的文本
subtitle1 TextFields 中使用的文本样式

本地化

如果您想覆盖固定文本或将其适配到不同语言,例如“关闭”、“下一步”等……您需要为 SurveyKit 提供一个翻译映射表。

SurveyKit(
    localizations: {
        'cancel': 'Cancel',
    }
);

这里是可覆盖键的完整列表

key value
cancel cancel
next next

开始调查

剩下要做的就是将调查问卷插入到 widget 树中,然后享受吧!

Scaffold(
    body: SurveyKit(
         onResult: (SurveyResult result) {
            //Evaluate results
          },
          task: OrderedTask(),
          theme: CustomThemeData(),
    )
);

? 自定义步骤

在某些时候,您可能需要定义自己的自定义问题步骤。例如,这可能是一个提示用户选择颜色值甚至声音样本的问题。这些尚未实现,但您可以轻松地自己创建它们。

您将需要一个 `CustomResult` 和一个 `CustomStep`。Result 类告诉 SurveyKit 您想保存哪些数据。

class CustomResult extends QuestionResult<String> {
    final String customData;
    final String valueIdentifier;
    final Identifier identifier;
    final DateTime startDate;
    final DateTime endDate;
    final String value; //Custom value
}

接下来您需要一个 CustomStep 类。建议使用 `StepView` widget 作为基础。它为您提供了 AppBar 和下一步按钮。

class CustomStep extends Step {
  final String title;
  final String text;

  CustomStep({
    @required StepIdentifier id,
    bool isOptional = false,
    String buttonText = 'Next',
    this.title,
    this.text,
  }) : super(isOptional, id, buttonText);

  @override
  Widget createView({@required QuestionResult questionResult}) {
      return StepView(
            step: widget.questionStep,
            result: () => CustomResult(
                id: id,
                startDate: DateTime.now(),
                endDate: DateTime.now(),
                valueIdentifier: 'custom'//Identification for NavigableTask,
                result: 'custom_result',
            ),
            title: Text('Title'),
            child: Container(), //Add your view here
        );
  }
}

如果您想创建一个完整的自定义视图,或者只是覆盖导航行为,您应该使用 SurveyController 及其三个方法

  • onNextStep()
  • onStepBack()
  • onCloseSurvey()

?vs? : Flutter SurveyKit、SurveyKit for AndroidResearchKit for iOS 的比较

这是对 iOS ResearchKit Surveys 提供哪些功能以及 SurveyKit for Android 已支持哪些功能的概述。目标是使所有三个库的功能保持一致。

? : 通过 JSON 创建您的调查问卷

您还可以通过 JSON 加载和创建您的调查问卷。这为您动态配置和交付不同的调查问卷提供了机会。用 JSON 创建您的调查问卷几乎与用 Dart 一样容易。只需调用 `dart Task.fromJson()` 并提供您的 JSON 文件或响应。JSON 应该看起来像这样

{
    "id": "123",
    "type": "navigable",
    "rules": [
        {
            "type": "conditional",
            "triggerStepIdentifier": {
                "id": "3"
            },
            "values": {
                "Yes": "2",
                "No": "10"
            }
        },
        {
            "type": "direct",
            "triggerStepIdentifier": {
                "id": "1"
            },
            "destinationStepIdentifier": {
                "id": "3"
            }
        },
        {
            "type": "direct",
            "triggerStepIdentifier": {
                "id": "2"
            },
            "destinationStepIdentifier": {
                "id": "10"
            }
        }
    ],
    "steps": [
        {
            "stepIdentifier": {
                "id": "1"
            },
            "type": "intro",
            "title": "Welcome to the\nQuickBird Studios\nHealth Survey",
            "text": "Get ready for a bunch of super random questions!",
            "buttonText": "Let's go!"
        },
        {
            "stepIdentifier": {
                "id": "2"
            },
            "type": "question",
            "title": "How old are you?",
            "answerFormat": {
                "type": "integer",
                "defaultValue": 25,
                "hint": "Please enter your age"
            }
        },
        {
            "stepIdentifier": {
                "id": "3"
            },
            "type": "question",
            "title": "Medication?",
            "text": "Are you using any medication",
            "answerFormat": {
                "type": "bool",
                "positiveAnswer": "Yes",
                "negativeAnswer": "No",
                "result": "POSITIVE"
            }
        },    
        {
            "stepIdentifier": {
                "id": "10"
            },
            "type": "completion",
            "text": "Thanks for taking the survey, we will contact you soon!",
            "title": "Done!",
            "buttonText": "Submit survey"
        }
    ]
}

完整的示例可以在 这里 找到

? 作者

此 Flutter 库由 QuickBird Studios 用 ? 创建。

❤️ 贡献

如果您需要帮助、发现错误或想讨论功能请求,请打开 issue。

如果您想对 SurveyKit 进行更改,请打开 PR。

? 许可证

SurveyKit 在 MIT 许可下发布。有关更多信息,请参阅 许可证

GitHub

查看 Github