SurveyKit: Create beautiful surveys with Flutter (inspired by iOS ResearchKit Surveys)
Do you want to display a questionnaire to get the opinion of your users? A survey for a medical trial? A series of instructions in a manual-like style? SurveyKit is a Flutter library that allows you to create exactly that.
Thematically it is built to provide a feeling of a professional research survey. The library aims to be visually clean, lean and easily configurable. We aim to keep the functionality close to iOS ResearchKit Surveys. We also created a SurveyKit version for native Android developers, check it out here
Examples
Flow
📚 Overview
- What SurveyKit does for you
- 🏃 Setup
- 💻 Usage
- 🔌 Plugin packages
- 📇 Custom rendering
- 🤖 JSON support
- 👤 Author
- ❤️ Contributing
- 📃 License
What SurveyKit does for you
- Simplifies the creation of surveys
- Provides rich animations and transitions out of the box
- Built with a consistent, lean, simple style to fit research purposes
- Survey navigation can be linear or based on a decision tree (directed graph)
- Gathers results and provides them in a convenient manner for further use
- Extensible answer and content rendering via a registry/plugin model
- Optional media plugins (
audio,video,lottie) - Gives you complete freedom on creating your own question types
- Provides an API and structure inspired by iOS ResearchKit Surveys
🏃 Setup
1. Add the dependency
pubspec.yaml
dependencies:
survey_kit: ^2.0.0-beta1
Add media packages only when you need them:
dependencies:
survey_kit_audio: ^2.0.0-beta1
survey_kit_video: ^2.0.0-beta1
survey_kit_lottie: ^2.0.0-beta1
2. Install it
flutter pub get
3. Import it
import 'package:survey_kit/survey_kit.dart';
💻 Usage
Create steps
To build a survey, create a list of Step objects. Each step can have a title, body content, and an answer format:
final steps = [
Step(
id: 'intro',
content: const [TextContent(text: 'Welcome to the survey')],
buttonText: 'Start survey',
),
Step(
id: 'name',
content: const [TextContent(text: 'What is your name?')],
answerFormat: const TextAnswerFormat(hint: 'Your name'),
buttonText: 'Continue',
),
Step(
id: 'age',
content: const [TextContent(text: 'How old are you?')],
answerFormat: const IntegerAnswerFormat(hint: 'Your age'),
buttonText: 'Continue',
),
Step(
id: 'done',
content: const [TextContent(text: 'Thanks for completing the survey!')],
buttonText: 'Submit survey',
),
];
The following answer formats are supported:
TextAnswerFormatIntegerAnswerFormatScaleAnswerFormatSingleChoiceAnswerFormatMultipleChoiceAnswerFormatBooleanAnswerFormat
Create a survey
Pass your steps to SurveyFlow and render it with the SurveyKit widget:
final task = SurveyFlow(id: 'my_survey', steps: steps);
SurveyKit(
task: task,
onResult: (SurveyResult result) {
// inspect result.finishReason and result.results
},
);
Branching surveys
When navigationRules is empty, the flow is sequential. Use ConditionalNavigationRule to build decision trees:
final task = SurveyFlow(
id: 'branching',
steps: [
Step(
id: 'medication',
content: const [TextContent(text: 'Are you using any medication?')],
answerFormat: SingleChoiceAnswerFormat(
textChoices: [
TextChoice(id: 'yes', value: 'yes', text: 'Yes'),
TextChoice(id: 'no', value: 'no', text: 'No'),
],
),
buttonText: 'Continue',
),
Step(id: 'yes-step', content: const [TextContent(text: 'Please list your medication.')], buttonText: 'Next'),
Step(id: 'no-step', content: const [TextContent(text: 'Great, no medication needed.')], buttonText: 'Next'),
Step(id: 'done', content: const [TextContent(text: 'Done!')], buttonText: 'Submit survey'),
],
navigationRules: {
'medication': ConditionalNavigationRule(
resultToStepIdentifierMapper: (_, input) {
final choice = input?.result as TextChoice?;
if (choice?.id == 'yes') return const NavigateToStep('yes-step');
if (choice?.id == 'no') return const NavigateToStep('no-step');
return const NavigateToNextInList();
},
),
},
);
Evaluate the results
When the survey finishes you receive a SurveyResult containing a list of StepResults and the FinishReason:
SurveyKit(
task: task,
onResult: (SurveyResult result) {
// result.finishReason — completed, discarded, etc.
// result.results — list of StepResult
final jsonResult = result.toJson();
},
);
Style
Styling is done through Flutter's standard theming. SurveyKit adapts to your ThemeData automatically.
Localization
Add SurveyKitLocalizations.delegate to your app's localization delegates:
MaterialApp(
localizationsDelegates: const [
SurveyKitLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: SurveyKitLocalizations.supportedLocales,
)
🔌 Plugin packages
Media and animation support is provided by dedicated packages. Register them via registries:
import 'package:survey_kit_audio/survey_kit_audio.dart';
import 'package:survey_kit_video/survey_kit_video.dart';
import 'package:survey_kit_lottie/survey_kit_lottie.dart';
SurveyKit(
task: task,
onResult: (result) {},
registries: [
SurveyKitAudio(),
SurveyKitVideo(),
SurveyKitLottie(),
],
);
📇 Custom rendering
Provide custom builders directly to SurveyKit for one-off answer or content types:
SurveyKit(
task: task,
onResult: (result) {},
answerViewBuilders: {
MyAnswerFormat: (format, step, stepResult) => MyAnswerView(
format: format as MyAnswerFormat,
),
},
contentWidgetBuilders: {
MyContent: (content) => MyContentWidget(content as MyContent),
},
);
For reusable extensions, implement SurveyKitPlugin and pass it via registries.
🤖 JSON support
Load a survey from JSON:
final survey = SurveyDefinition.fromJson(jsonMap);
For custom or plugin types, register JSON factories before deserializing:
AnswerFormat.registerFromJson('my_answer', MyAnswerFormat.fromJson);
Content.registerFromJson('my_content', MyContent.fromJson);
// Plugin types
Content.registerFromJson(AudioContent.type, AudioContent.fromJson);
Content.registerFromJson(VideoContent.type, VideoContent.fromJson);
Content.registerFromJson(LottieContent.type, LottieContent.fromJson);
👤 Author
This Flutter library is created with 💙 by QuickBird Studios.
❤️ Contributing
Open an issue if you need help, if you found a bug, or if you want to discuss a feature request.
Open a PR if you want to make changes to SurveyKit.
📃 License
SurveyKit is released under an MIT license. See License for more information.
Libraries
- gen/survey_kit_localizations
- gen/survey_kit_localizations_en
- survey_kit
- The main entry point for the survey_kit package.