Customize how a Questionnaire is displayed
The Structured Data Capture Library provides default UI components and styles to render FHIR Questionnaire resources based on Material Design and the Structured Data Capture Implementation Guide. In practice, you may want to customize how questionnaires look, and this guide explains the two primary ways to do so:
- Adjust the existing components to match the style of the rest of your application
- Create new components to collect information in non-standard ways, e.g. connected devices
Customize styles
The Structured Data Capture Library includes a default theme Theme.Questionnaire
which defines a number of custom attributes used to style questionnaires. For example, questionnaireQuestionTextStyle
defines the style for all question text, and changing it affects all rendered questionnaires. The custom attributes are:
groupHeaderTextAppearanceQuestionnaire
questionnaireQuestionTextStyle
questionnaireSubtitleTextStyle
questionnaireRadioButtonStyle
questionnaireCheckBoxStyle
questionnaireDropDownTextStyle
questionnaireDropdownLayoutStyle
questionnaireTextInputLayoutStyle
questionnaireTextInputEditTextStyle
questionnaireChipStyle
questionnaireDialogTitleStyle
questionnaireDialogButtonStyle
questionnaireAddAnotherAnswerButtonStyle
questionnaireErrorTextStyle
questionnaireButtonStyle
questionnaireSubmitButtonStyle
To customize the styles used to render questionnaires, create a theme with different values for the custom attributes. A simple way to do this is to extend the Theme.Questionnaire
theme and override the attributes you want to change.
For example, to change the appearance of question text, open your project's res/values/styles.xml
file and add a new theme that extends Theme.Questionnaire
, then set the headerTextAppearanceQuestionnaire
attribute to your preferred value:
<style name="Theme.MyQuestionnaire" parent="Theme.Questionnaire">
<item name="questionnaireQuestionTextStyle">
@style/TextAppearance.MaterialComponents.Subtitle2
</item>
</style>
Next, edit your application's default theme, typically in the res/values/themes.xml
file, and add the attribute questionnaire_theme
set to the new theme you just created:
<style name="Theme.MyApplication" parent="Theme.Material3.DayNight.NoActionBar">
...
<item name="questionnaire_theme">@style/Theme.MyQuestionnaire</item>
</style>
Custom questionnaire components
The Structured Data Capture Library uses custom UI components to render questions in a questionnaire. There are predefined components for most question item types so you do not need to do anything special for most questions. However, if you want to render a question in a way not described in the FHIR standard of the SDC implementation guide, you can create a custom component.
Create a custom component
In order to create a custom component:
- Create a layout for the custom component (example).
- Create a class for your component that implements
QuestionnaireItemViewHolderFactory
(example). In that class:- Pass the layout resource for your custom component in the constructor of your custom factory.
- Override the
getQuestionnaireItemViewHolderDelegate()
function. It must return aQuestionnaireItemViewHolderDelegate
which implements the following functions:
init
: a delegate function for theinit
function ofRecyclerView.ViewHolder
bind
: a delegate function for thebind
function ofRecyclerView.ViewHolder
displayValidationResult
: displays the validation result for the answer(s) provided by the usersetReadOnly
: configures the UI based on the read-only status of the questionnaire item
Apply a custom component to questions
Now that you have defined the custom widget and its behavior, it is time to configure the Structured Data Capture Library in order for the custom widget to be applied to the appropriate questions.
- Create a QuestionnaireFragment.QuestionnaireItemViewHolderFactoryMatcher (example) that defines:
- factory: The custom component factory to use.
- matches: A predicate function which, given a
Questionnaire.QuestionnaireItemComponent
, returns true if the factory should apply to that item.
- Create a custom implementation of
QuestionnaireFragment
that overridesgetCustomQuestionnaireItemViewHolderFactoryMatchers
(example). It should return a list that contains yourQuestionnaireItemViewHolderFactoryMatcher
. - When rendering your questionnaire, use your custom implementation of
QuestionnaireFragment
instead.
Localize questionnaires
When rendering your questionnaire, the library will look for the translation extension, and if the lang element matches the application default locale, will use the value of the content element of the extension instead of the text element of the questionnaire item. You can also use the Locale.setDefault()
method to manually set the locale to check against.