SurveyKit
使用 Flutter 创建精美调查(灵感来自 iOS ResearchKit Surveys)
您想向用户展示问卷以获取他们的意见吗?医疗试验的调查?手册风格的系列说明?
SurveyKit是一个Flutter库,可让您创建这样的内容。
在主题上,它旨在提供专业研究调查的感觉。该库旨在视觉上干净、精简且易于配置。我们的目标是使功能接近iOS ResearchKit调查。我们还为原生Android开发者创建了SurveyKit版本,请在此处查看。
这是早期版本,仍在开发中。请随时通过issues提供反馈、想法或改进建议。
示例
流程
屏幕截图
![]() |
![]() |
![]() |
![]() |
![]() |
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指定了您想问的问题类型(问题答案的类型)。目前支持这些类型
TextAnswerFormatIntegerAnswerFormatScaleAnswerFormatSingleChoiceAnswerFormatMultipleChoiceAnswerFormatBooleanAnswerFormat
剩下要做的就是将您的步骤收集到一个列表中,或在小部件中内联添加它们。
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主题调整样式。
开始调查
剩下要做的就是将调查插入到小部件树中,尽情享受吧!
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小部件作为基础。它为您提供了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()




