Skip to content
CARP Docs
Ask AISystemLightDark
On this page

Answer formats

The seven answer formats of a question step, what the participant sees and the value each one stores.

Copy MarkdownOpen inOpen in GitHubView as MarkdownOpen in Scira AIOpen in ChatGPTOpen in ClaudeOpen in Cursor

An answer format decides how the participant answers a question step and which value the step stores as its answer. Every format extends RPAnswerFormat, and a question step takes one as answerFormat, also inside a form step.

Answer formatThe participantAnswer value
RPChoiceAnswerFormatSelects one or more optionsList<RPChoice>
RPIntegerAnswerFormatTypes a whole numberString
RPDoubleAnswerFormatTypes a decimal numberString
RPSliderAnswerFormatMoves a sliderdouble
RPImageChoiceAnswerFormatTaps one of several imagesRPImageChoice
RPDateTimeAnswerFormatTurns the wheels of a date or time pickerString
RPTextAnswerFormatTypes free textString

The step stores the value under the key answer in the results map of its RPStepResult. Until the participant gives a valid answer, the answer is null and NEXT stays disabled. For how to read the values, see Answer values.

Choice

RPChoiceAnswerFormat lists options as rows, with a radio button for a single choice or a checkbox for multiple choice. Above the rows, the step shows "(Choose one option)" or "(Choose one or more options)".

ParameterTypeRequiredDescription
answerStyleRPChoiceAnswerStyleYesSingleChoice or MultipleChoice.
choicesList<RPChoice>YesThe options, in the order shown.

Each option is an RPChoice:

ParameterTypeRequiredDefaultDescription
textStringYes—The label of the option.
valueintYes—The value of the option, such as its score on a scale. Navigation rules match on it.
detailTextString?No—A longer text behind an info icon at the end of the row, shown on a page of its own.
isFreeTextboolNofalseTurns the label into a text field, with text as its hint.

A multiple choice question with an explained option and a free-text option:

final activities = RPQuestionStep(
  identifier: 'activities',
  title: 'What did you do for exercise this week?',
  answerFormat: RPChoiceAnswerFormat(
    answerStyle: RPChoiceAnswerStyle.MultipleChoice,
    choices: [
      RPChoice(text: 'Walking', value: 1),
      RPChoice(text: 'Cycling', value: 2),
      RPChoice(
        text: 'Strength training',
        value: 3,
        detailText: 'Exercise with weights, machines or your own body weight.',
      ),
      RPChoice(text: 'Something else', value: 9, isFreeText: true),
    ],
  ),
);

The answer is a list of the selected RPChoice objects, in the order the participant selected them. It is a list for a single choice too, with one element. For example, after the participant selects Cycling, types "Climbing" into the free-text option and selects it, the results map of the step holds:

{
  "answer": [
    { "__type": "RPChoice", "text": "Cycling", "value": 2, "isFreeText": false },
    { "__type": "RPChoice", "text": "Climbing", "value": 9, "isFreeText": true }
  ]
}

The options behave as follows:

  • In a single choice, tapping the selected option clears the selection, and the answer becomes null.
  • Typing into a free-text option does not select it: the participant also taps its radio button or checkbox.
  • The typed text replaces text of the free-text option, in the answer and in the task itself. Build a new task for the next run.

A yes or no question is a single choice with two options: Research Package has no Boolean answer format.

Integer

RPIntegerAnswerFormat shows a text field with the hint "Tap to answer" and a number keyboard.

ParameterTypeRequiredDefaultDescription
minValueintYes—The lowest accepted value.
maxValueintYes—The highest accepted value.
suffixString?No—A unit at the end of the field, such as kg.

A question about weight:

final weight = RPQuestionStep(
  identifier: 'weight',
  title: 'What is your weight?',
  answerFormat: RPIntegerAnswerFormat(
    minValue: 30,
    maxValue: 250,
    suffix: 'kg',
  ),
);

The field accepts whole numbers from minValue to maxValue, both included. For other input, it shows "Input a number" or "Should be between 30 and 250", and the answer stays null. The answer is the typed text as a String, such as "72", not an int.

Decimal number

RPDoubleAnswerFormat works like the integer format, with a keyboard that offers a decimal separator.

ParameterTypeRequiredDefaultDescription
minValuedoubleYes—The lowest accepted value.
maxValuedoubleYes—The highest accepted value.
suffixString?No—A unit at the end of the field, such as °C.

A question about body temperature:

final temperature = RPQuestionStep(
  identifier: 'temperature',
  title: 'What is your body temperature?',
  answerFormat: RPDoubleAnswerFormat(minValue: 34, maxValue: 43, suffix: '°C'),
);

The answer is the typed text as a String, such as "37.5". The field accepts only a period as the decimal separator: a comma, which keyboards in many languages offer, gives "Input a number".

Slider

RPSliderAnswerFormat shows a Material slider in a card, with the selected value above it.

ParameterTypeRequiredDefaultDescription
minValuedoubleYes—The value at the left end.
maxValuedoubleYes—The value at the right end.
divisionsintYes—The number of intervals between the ends. For whole numbers, use maxValue minus minValue.
prefixString?No''Text before the value.
suffixString?No''Text after the value.

A stress rating on a 0–10 scale:

final stress = RPQuestionStep(
  identifier: 'stress',
  title: 'How stressed do you feel right now?',
  answerFormat: RPSliderAnswerFormat(
    minValue: 0,
    maxValue: 10,
    divisions: 10,
    suffix: ' of 10',
  ),
);

The label joins prefix, the value and suffix without spaces, so include any space in them; this example shows "7.0 of 10". The answer is a double, such as 7.0.

The thumb starts at minValue, and the question counts as answered only after the participant moves it. To answer minValue, the participant moves the thumb away and back.

Image choice

RPImageChoiceAnswerFormat shows the images in rows, each in a 72-pixel square. The participant taps one image, which gets a round border in the primary color. Its description then replaces the text "Select an image" below the images.

ParameterTypeRequiredDescription
choicesList<RPImageChoice>YesThe images, in the order shown.

Each image is an RPImageChoice:

ParameterTypeRequiredDefaultDescription
imageUrlStringYes—The asset key of the image, such as assets/images/happy.png. URLs do not work here.
descriptionStringYes—The text shown when the image is selected.
valuedynamicNo—The value of the choice. Use a value that JSON can encode, such as a number or a string.
keyString?No—Not used.

A mood question with three images:

final mood = RPQuestionStep(
  identifier: 'mood',
  title: 'How do you feel right now?',
  answerFormat: RPImageChoiceAnswerFormat(
    choices: [
      RPImageChoice(
        imageUrl: 'assets/images/sad.png',
        value: -1,
        description: 'Sad',
      ),
      RPImageChoice(
        imageUrl: 'assets/images/neutral.png',
        value: 0,
        description: 'Neutral',
      ),
      RPImageChoice(
        imageUrl: 'assets/images/happy.png',
        value: 1,
        description: 'Happy',
      ),
    ],
  ),
);

The answer is the selected RPImageChoice itself, not a list. Tapping the selected image again clears the answer. To add the images to your app, see Add media and sound assets.

Date and time

RPDateTimeAnswerFormat shows an iOS-style wheel picker on both platforms. It uses the 24-hour clock when the device does.

ParameterTypeRequiredDescription
dateTimeAnswerStyleRPDateTimeAnswerStyleYesDate, TimeOfDay or DateAndTime.

A question about the time of waking up:

final wakeUp = RPQuestionStep(
  identifier: 'wakeUp',
  title: 'When did you wake up today?',
  answerFormat: RPDateTimeAnswerFormat(
    dateTimeAnswerStyle: RPDateTimeAnswerStyle.TimeOfDay,
  ),
);

The answer is a String from DateTime.toString() in local time, which DateTime.parse() reads back:

StyleWheelsExample answer
DateDay, month and year"2026-10-25 00:00:00.000", at midnight
TimeOfDayHour and minute"2026-10-27 07:30:00.000", on the day the question is answered
DateAndTimeDate, hour and minute"2026-10-26 21:15:00.000"

The picker starts at the current date and time, and the participant cannot turn it past them. A Date or DateAndTime question therefore takes no future dates, and a TimeOfDay question takes no time later than the current time of day. To ask for a later time, such as a planned bedtime, use a choice question.

The question counts as answered only after the participant turns a wheel. To answer the current date or time, the participant turns a wheel away and back.

Text

RPTextAnswerFormat shows an outlined text field that is 10 lines high. Longer text scrolls inside the field.

ParameterTypeRequiredDefaultDescription
hintTextString?No—A hint in the empty field.
autoFocusboolNofalseOpens the keyboard when the question appears.
disableHelpersboolNofalseTurns off autocorrect and suggestions, for example in a typing test.

An optional question with free text:

final notes = RPQuestionStep(
  identifier: 'notes',
  title: 'Is there anything else you want to tell the study team?',
  answerFormat: RPTextAnswerFormat(hintText: 'Write your answer here'),
  optional: true,
);

The answer is the text as a String. An empty field gives null.

Question types

Each answer format sets its questionType, a value of RPQuestionType that appears in the JSON of tasks and results:

Answer formatquestionType
RPChoiceAnswerFormatSingleChoice or MultipleChoice, from answerStyle
RPIntegerAnswerFormatInteger
RPDoubleAnswerFormatDouble
RPSliderAnswerFormatScale
RPImageChoiceAnswerFormatImageChoice
RPDateTimeAnswerFormatDate, TimeOfDay or DateAndTime, from dateTimeAnswerStyle
RPTextAnswerFormatText
RPFormAnswerFormatForm, set by every form step

The enum also has None, Decimal, Boolean and Duration, which no answer format uses. The steps choose their input from the class of the answer format, not from questionType. For tasks in JSON, see JSON surveys.

Quick links

Page · DocumentationCARP DocumentationPage · DocumentationIntroductionPage · DocumentationQuickstartPage · DocumentationTerminologyPage · DocumentationArchitecture