survey_kit 2.0.0-beta2 copy "survey_kit: ^2.0.0-beta2" to clipboard
survey_kit: ^2.0.0-beta2 copied to clipboard

Create beautiful surveys with Flutter (inspired by iOS ResearchKit Surveys)

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 #

  • 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:

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

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.

126
likes
60
points
1.83k
downloads

Documentation

API reference

Publisher

verified publisherquickbirdstudios.com

Weekly Downloads

Create beautiful surveys with Flutter (inspired by iOS ResearchKit Surveys)

License

MIT (license)

Dependencies

collection, flutter, flutter_localizations, flutter_markdown_plus, intl, json_annotation, meta, url_launcher, uuid

More

Packages that depend on survey_kit