Flutter library to create beautiful surveys (aligned with ResearchKit on iOS)

Overview

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 an 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

This is an early version and work in progress. Do not hesitate to give feedback, ideas or improvements via an issue.

Examples

Flow

Screenshots

πŸ“š Overview: Creating Research Surveys

What SurveyKit does for you

  • Simplifies the creation of surveys
  • Provides rich animations and transitions out of the box (custom animations planned)
  • Build 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 convinient manner to the developer for further use
  • Gives you complete freedom on creating your own questions
  • Allows you to customize the style
  • Provides an API and structure that is very similar to iOS ResearchKit Surveys

What SurveyKit does not (yet) do for you

As stated before, this is an early version and a work in progress. We aim to extend this library until it matches the functionality of the iOS ResearchKit Surveys.

πŸƒ Setup

To use this plugin, add flutter_surveykit as a dependency in your pubspec.yaml file.

1. Add the dependecy

pubspec.yaml

dependencies:
  surveykit: ^0.1

2. Install it

flutter pub get

3. Import it

import 'package:survey_kit/survey_kit.dart';

πŸ’» Usage

Example

A working example project can be found HERE

Create survey steps

To create a step, create an instance of one of these 3 classes:

InstructionStep

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

The title is the general title of the Survey you want to conduct.
The text is, in this case, the introduction text which should give an introduction, about what the survey is about.
The buttonText specifies the text of the button, which will start the survey. All of these properties have to be resource Ids.

CompletionStep

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

The title is the general title of the Survey you want to conduct, same as for the InstructionStep.
The text is here should be something motivational: that the survey has been completed successfully.
The buttonText specifies the text of the button, which will end the survey. All of these properties have to be resource Ids.

QuestionStep

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

The title same as for the InstructionStep and CompletionStep.
The text the actual question you want to ask. Depending on the answer type of this, you should set the next property.
The answerFormat specifies the type of question (the type of answer to the question) you want to ask. Currently there these types supported:

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

All that's left is to collect your steps in a list or add them inline in the widget.

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

Create a Task

Next you need a task. Each survey has exactly one task. A Task is used to define how the user should navigate through your steps.

OrderedTask

var task = OrderedTask(steps: steps)

The OrderedTask just presents the questions in order, as they are given.

NavigableOrderedTask

var task = NavigableOrderedTask(steps: steps)

The NavigableOrderedTask allows you to specify navigation rules.
There are two types of navigation rules:

With the DirectStepNavigationRule you say that after this step, another specified step should follow.

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

With the MultipleDirectionStepNavigationRule you can specify the next step, depending on the answer of the step.

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;
      }
    },
  ),
);

Evaluate the results

When the survey is finished, you get a callback. No matter of the FinishReason, you always get all results gathered until now.
The SurveyResult contains a list of StepResults and the FinishReason. The StepResult contains a list of QuestionResults.

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

Style

There are already many adaptive elements for Android and IOS implemented. In the future development other parts will be adapted too. The styling can be adjusted by the build in Flutter theme.

Start the survey

All that's left is to insert the survey in the widget tree and enjoy. πŸŽ‰ 🎊

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

πŸ“‡ Custom steps

At some point, you might wanna define your own custom question steps. That could, for example, be a question which prompts the user to pick color values or even sound samples. These are not implemented yet but you can easily create them yourself:

You'll need a CustomResult and a CustomStep. The Result class tells SurveyKit which data you want to save.

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
}

Next you'll need a CustomStep class. It is recommended to use the StepView widget as your foundation. It gives you the AppBar and the next button.

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,
            controller: SurveyController(
              context: context,
              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
        );
  }
}

If you want to create a complete custom view you should use the SurveyController with its three methods:

  • nextStep()
  • stepBack()
  • closeSurvey()

🍏 vs πŸ€– : Comparison of Flutter SurveyKit, SurveyKit on Android to ResearchKit on iOS

This is an overview of which features iOS ResearchKit Surveys provides and which ones are already supported by SurveyKit on Android. The goal is to make all three libraries match in terms of their functionality.

πŸ‘€ 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.

Comments
  • For `SingleChoiceAnswerFormat`,  `isOptional` flag not working

    For `SingleChoiceAnswerFormat`, `isOptional` flag not working

        this.questions.asMap().forEach((index, each) => {
              choices = [],
              each['options'].forEach((eachOption) {
                choices.add(TextChoice(
                    text: capitalize(eachOption['text']),
                    value: eachOption['text']));
              }),
              steps.add(QuestionStep(
                  isOptional: false,
                  id: StepIdentifier(id: index.toString()),
                  title: 'Question ' + index.toString() + '/' + total.toString(),
                  text: each['question'],
                  answerFormat: SingleChoiceAnswerFormat(
                      defaultSelection: null, textChoices: choices)))
            });
    

    Even if I mark the isOptional false, I am able to skip the question by clicking next button, my Goal is to restrict the user.

    bug 
    opened by sohail0992 7
  • Results not publishing on stepBack and stepForward

    Results not publishing on stepBack and stepForward

    simulator_screenshot_9C938B4E-F3ED-40A8-B9C9-D6F93D472E6D

    I have verified the same issue for all the steps. The result object is stored properly in the example app on the main branch. However, it's coming as null in initState for each step view.

    bug 
    opened by tushkaty 5
  • First question textChoices repeating for every question when answerFormat:  SingleChoiceAnswerFormat has been added for multiple steps

    First question textChoices repeating for every question when answerFormat: SingleChoiceAnswerFormat has been added for multiple steps

    I have added the question to survey kit in below format.

    
       steps.add(InstructionStep(
          title: 'Welcome to Lab Survey',
          text: 'Get ready for a bunch of questions!',
          buttonText: 'Let\'s go!',
        ));
        steps.add(
          QuestionStep(
            title: 'Done?',
            text: 'We are done, do you mind to tell us more about yourself?',
            answerFormat: SingleChoiceAnswerFormat(
              textChoices: [
                TextChoice(text: 'Yes', value: 'Yes'),
                TextChoice(text: 'No', value: 'No'),
              ],
            ),
          ),
        );
        steps.add(
          QuestionStep(
            title: 'Done?',
            text: 'kjdsfkjaskdfj?',
            answerFormat: SingleChoiceAnswerFormat(
              textChoices: [
                TextChoice(text: 'none', value: 'none'),
                TextChoice(text: 'none', value: 'noe'),
              ],
            ),
          ),
        );
    
    

    and returning the task to suveyKit task,

     var task = NavigableTask(id: TaskIdentifier(), steps: steps);
     return task;
    

    Issue is on pressing next, the question changes but options remain the same.

    bug 
    opened by sohail0992 5
  • Finish quiz

    Finish quiz

    Hi, I have a question regarding when the questionnaire is finished. I'm using the example from the page. However, when the questionnaire ends, the application goes to a completely black screen. I would like to know how do I go to a custom screen. What I want is to present a simple screen saying that the questionnaire has already been answered.

    question 
    opened by Bruno12leonel 5
  • Change font size of survey elements

    Change font size of survey elements

    Hi,

    I'd like to change the font style of the survey elements. I tried overriding the textTheme in SurveyKit().

    I found out that headline6 is used for e.g. question type title and selected value (scale). I was able to change color and font size here. However, I wasn't able to change the font size for "type" "intro" (note: I'm using json import). It seems that bodytext2 is used b/c I could change the color - but not the size. Am I missing something?

    Thanks in advance.

    opened by PeteSahad 4
  • Getting error when running `flutter build apk` on project in which survey_kit is imported

    Getting error when running `flutter build apk` on project in which survey_kit is imported

    /opt/hostedtoolcache/flutter/2.4.0-4.2.pre-beta/x64/.pub-cache/hosted/pub.dartlang.org/survey_kit-0.0.11/lib/src/views/time_answer_view.dart:82:14: Error: 'TimePickerDialog' is imported from both 'package:flutter/src/material/time_picker.dart' and 'package:survey_kit/src/views/widget/time_picker.dart'.
          child: TimePickerDialog(
    
    bug 
    opened by sohail0992 4
  • Cancel Button Behaviours

    Cancel Button Behaviours

    Is there an option to override the cancel option behaviour ? or do i have to modify the library

    The entire page gets popped if i tap on cancel, I want it to behave like the back button of a scaffold.

    enhancement question 
    opened by satyajitghana 4
  • Using SurveyKit in a Future for API database loading

    Using SurveyKit in a Future for API database loading

    Hi, I'd like to congratulate you on this excellent work you did here. I just have a question that I'm sure is due to my lack of expertise with Flutter/Dart, than with your work. I'm trying to load the questions from a database through a NodeJS API & Mongo DB as backend, everything seem to work just fine, but when I call SurveyKit from a Future Builder (see code below), as soon as I tap/click on the Answer text field it takes me immediately the InstructionsStep screen. Can you please guide me on what am I missing here? ... FutureBuilder( future: getQuestionSteps(surveyId:'1'), builder: (ctx, snapshot) { // Checking if future is resolved or not if (snapshot.connectionState == ConnectionState.done) { // If we got an error if (snapshot.hasError) { return Center( child: Text( '${snapshot.error} occured', style: TextStyle(fontSize: 18), ), ); // if we got our data } else if (snapshot.hasData) { // Extracting data from snapshot object final questionSteps = snapshot.data; return Survey.SurveyKit( onResult: (Survey.SurveyResult result) { print(result.finishReason); }, task: getSampleTask() ); } } // Displaying LoadingSpinner to indicate waiting state return Center( child: CircularProgressIndicator(), ); }, )

    question 
    opened by ghost 4
  • SurveyResult toJson

    SurveyResult toJson

    Hey guys,

    Awesome plugin, great work!

    I've been playing around with it in the last couple of a days and plan on using it in my current project. I would need to export the survey results to json though and saw (on another thread + in the code) that it's not implemented yet.

    Just wanted to check with you: did you start that at any point?

    I took a quick look on how to do it and at this stage I think I would just go ahead, use freezed and make all the subclasses of QuestionResult (BooleanQuestionResult, DateQuestionResult etc) serializable...

    Did you maybe see any potential problems with that approach?

    Cheers

    opened by ezmegy 3
  • Multiple Double Answer Format

    Multiple Double Answer Format

    Creation of a new Answer Format called Multiple Double Answer Format. This answer format shows in display more than 1 text field for insert double values.

    opened by soaresg 3
  • Unable to load in getJsonTask() from example code

    Unable to load in getJsonTask() from example code

    When I try to run the following getJsonTask() from the example code, the app just stays on the loading screen for some time. Using Flutter 3.0.1

    class _MyAppState extends State<MyApp> {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: Container(
              color: Colors.white,
              child: Align(
                alignment: Alignment.center,
                child: FutureBuilder<Task>(
                  future: getJsonTask(), //HERE
                  builder: (context, snapshot) {
                         .....
    

    Running getSampleTask() it works fine.

    opened by gerryau 3
  • Added/Fixed default values for TextAnswerView and BooleanAnswerView

    Added/Fixed default values for TextAnswerView and BooleanAnswerView

    defaultValue attribute was missing/not used from TextAnswerFormat and BooleanAnswerFormat. In this PR they're added.

    It contains commits from this PR as well, https://github.com/QuickBirdEng/survey_kit/pull/92 Please let's clear up https://github.com/QuickBirdEng/survey_kit/pull/92 so that I can sync them and this one will become more clearer.

    opened by saiful-apx 2
  • Controller's length property (19) does not match the number of children (37) present in TabBarView's children property.

    Controller's length property (19) does not match the number of children (37) present in TabBarView's children property.

    First of all thanks for this beautiful package! :)

    When the keyboard appear (to write in TextAnswerFormat), the app crash and got this error

    Controller's length property (19) does not match the number of children (37) present in TabBarView's children property.

    bug 
    opened by soufiane0123 1
  • json schema validation

    json schema validation

    It would be great to have json schema defined so you can validate the survey task from the backend so you don't have to find out it is not working when a user tries to load it.

    enhancement 
    opened by ayushin 0
  • Update survey default values with data from DB when filling survey

    Update survey default values with data from DB when filling survey

    Hello I created survey with survey_kit commit: 41f32291e87b4c0e41f75b9d7e6bebaa3723a6c9. At the beginning of the survey, the person's ID is asked. After inserting the person id, I want to check in the DB if the person already exists. If yes, the default survey values will be replaced with the values from the DB. Can I do it and how? Also, I want to log after every step that goes through in the survey. Can I do it and how? Thanks in advance

    enhancement 
    opened by VladEfanovNewton 4
  • Develop of file upload answer format

    Develop of file upload answer format

    I'm developing a new answer format that you can upload a file and a description on a question step. I would like to know if there is some example or some ongoing code you can provide me so I can base on it.

    Appreciate.

    enhancement question 
    opened by soaresg 1
  • VideoStepResult usage example

    VideoStepResult usage example

    Hi, I'm working on a research application that needs to show users some videos, I saw that survey_kit has a VideoStepResult and depends on video_player, is there a code sample for a VideoStep?

    enhancement 
    opened by augustozanellato 1
Owner
QuickBird Studios
Overly friendly team of developers driven to push the state of Mobile Development forward (we're hiring!)
QuickBird Studios
A Flutter project to take surveys of talks using emoticons πŸ˜€

smilemeter A Flutter project to take surveys of talks using emoticons ?? . The idea is to put a person in the exit way and get feedbacks from the publ

Salvatore Giordano 6 Feb 15, 2021
This is a beautiful neumorphic noticeboard app for Guru Gobind Singh Indraprastha University. This works on both Android and iOS.

GGSIPU Noticeboard App This is a beautiful neumorphic noticeboard app for Guru Gobind Singh Indraprastha University. This works on both Android and iO

Hash Studios 20 Nov 10, 2022
A Flutter widget to create an iOS settings-table (static TableView).

flutter_cupertino_settings A Flutter widget to create an iOS settings-table (static TableView). import 'package:flutter_cupertino_settings/flutter_cup

Matthias Rupp 234 Dec 28, 2022
Paystack SDK for iOS. Accept Payments on iOS

Paystack iOS SDK The Paystack iOS SDK make it easy to collect your users' credit card details inside your iOS app. By charging the card immediately on

Paystack 22 May 29, 2022
Flutter-task-planner-app - A beautiful task planner app design made in flutter.

Flutter Task Planner App Design Task Planner App is built with flutter. App design is based on Task Planner App designed by Purrweb UI. This app is st

Sourav Kumar Suman 692 Jan 2, 2023
πŸ¦‹Beautiful flutter app for downloading Instagram stories πŸš€

NOTE: No longer maintained Instory ?? ?? Beautiful flutter app for downloading Instagram stories ?? Demo video Dependencies used video_player http dio

Sarath 204 Dec 16, 2022
Nimbus is a beautiful portfolio design built using flutter

nimbus This is Nimbus (Portfolio & CV), a beautifully designed portfolio website built with flutter. It is inspired by Web Genius Lab Designs on Behan

David-Legend 196 Dec 26, 2022
Flutter weather application with beautiful UI and UX.

β˜€οΈ Feather Beautiful Flutter weather application. Entirely written in Dart and Flutter. Application is ready for Android and iOS. ?? Media ☁️ Features

Jakub 559 Jan 5, 2023
This is an eCommerce minimalist template with a clean and beautiful design for Flutter.

Shope - Free Flutter eCommerce Template The β€œShope” e-Commerce UI Kit has the goal to help you to save time with the frontend development. You can use

Roberto Juarez 1.1k Jan 8, 2023
A flutter app to generate beautiful, high-quality screenshots of tweets from twitter.

tweet_png A flutter app to generate beautiful, high-quality screenshots of tweets from twitter. Follow on Instagram for more using the app get your tw

Ananthu P Kanive 51 Sep 23, 2022
A beautiful drawing view for a your flutter application with single line of code

Flutter Draw A beautiful drawing view for a your flutter application with single line of code. To start with this, we need to simply add the dependenc

Sanskar Tiwari 69 Dec 26, 2022
A Beautiful Windows 11 UI Built With Flutter

Windows 11 Redesign Depois de um tempo sem trabalhar com Flutter decidi fazer uma interface baseado no Windows 11, espero que vocΓͺs gostem e deixem o

Dorivaldo dos Santos 32 Dec 1, 2022
A beautiful navigation bar to use in flutter

Beauty Navigation A beautiful navigation bar to use in flutter Inspired from the #dribbble shot by Mauricio Bucardo @m.bucardo Usage Add the Package i

Poojan Pandya 21 Oct 26, 2021
A simple and beautiful animated app bar created with Flutter.

Animated App Bar Flutter application showcasing the creation of an animated app bar. End Result Relevant YouTube Video https://youtu.be/SkkmoT_DZUA Ge

Vihar 23 Jan 15, 2022
A chatting app made with Flutter and FireBase. It supports GIPHY gifs, images, stcikers, dark mode, custom animations, google login, online storage, beautiful UI and more.

ChatMe A Flutter based chatting app which lets user chat from random peoples or strangers, has GIPHY gif support, sitckers, custom animations, dark mo

Hash Studios 20 Nov 7, 2022
A Beautiful Movie App With Flutter And Themoviedb.Org API

Movie Flutter Application Movie Application Flutter Flutter allows you to build beautiful native apps on iOS and Android Platforms from a single codeb

Falah Hassan 5 Jun 5, 2022
A Beautiful Onboarding UI Screen For Flutter

onboarding_ui Untitled.design.mp4

Ramesh M S 9 Apr 7, 2022
A beautiful todo app made with Flutter

Todo - Simple & Beautiful A minimal Todo mobile app made using Flutter. Key Features β€’ How To Use β€’ Download β€’ Credits β€’ Key Features Easily add and r

Sabin 424 Dec 27, 2022
Beautiful Quran Majeed app with aesthetic Animation.

quran_app A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if thi

Abdul Wadood 14 Oct 17, 2022