use of org.odk.collect.android.logic.ImmutableDisplayableQuestion in project collect by opendatakit.
the class FormEntryActivity method updateFieldListQuestions.
/**
* Saves the form and updates displayed widgets accordingly:
* - removes widgets corresponding to questions that are no longer relevant
* - adds widgets corresponding to questions that are newly-relevant
* - removes and rebuilds widgets corresponding to questions that have changed in some way. For
* example, the question text or hint may have updated due to a value they refer to changing.
* <p>
* The widget corresponding to the {@param lastChangedIndex} is never changed.
*/
private void updateFieldListQuestions(FormIndex lastChangedIndex) throws RepeatsInFieldListException {
// Save the user-visible state for all questions in this field-list
FormEntryPrompt[] questionsBeforeSave = getFormController().getQuestionPrompts();
List<ImmutableDisplayableQuestion> immutableQuestionsBeforeSave = new ArrayList<>();
for (FormEntryPrompt questionBeforeSave : questionsBeforeSave) {
immutableQuestionsBeforeSave.add(new ImmutableDisplayableQuestion(questionBeforeSave));
}
saveAnswersForCurrentScreen(questionsBeforeSave, immutableQuestionsBeforeSave);
FormEntryPrompt[] questionsAfterSave = getFormController().getQuestionPrompts();
Map<FormIndex, FormEntryPrompt> questionsAfterSaveByIndex = new HashMap<>();
for (FormEntryPrompt question : questionsAfterSave) {
questionsAfterSaveByIndex.put(question.getIndex(), question);
}
// Identify widgets to remove or rebuild (by removing and re-adding). We'd like to do the
// identification and removal in the same pass but removal has to be done in a loop that
// starts from the end and itemset-based select choices will only be correctly recomputed
// if accessed from beginning to end because the call on sameAs is what calls
// populateDynamicChoices. See https://github.com/getodk/javarosa/issues/436
List<FormEntryPrompt> questionsThatHaveNotChanged = new ArrayList<>();
List<FormIndex> formIndexesToRemove = new ArrayList<>();
for (ImmutableDisplayableQuestion questionBeforeSave : immutableQuestionsBeforeSave) {
FormEntryPrompt questionAtSameFormIndex = questionsAfterSaveByIndex.get(questionBeforeSave.getFormIndex());
// bypass SelectChoices stored in ImmutableDisplayableQuestion
if (questionBeforeSave.sameAs(questionAtSameFormIndex) && !getFormController().usesDatabaseExternalDataFeature(questionBeforeSave.getFormIndex())) {
questionsThatHaveNotChanged.add(questionAtSameFormIndex);
} else if (!lastChangedIndex.equals(questionBeforeSave.getFormIndex())) {
formIndexesToRemove.add(questionBeforeSave.getFormIndex());
}
}
for (int i = immutableQuestionsBeforeSave.size() - 1; i >= 0; i--) {
ImmutableDisplayableQuestion questionBeforeSave = immutableQuestionsBeforeSave.get(i);
if (formIndexesToRemove.contains(questionBeforeSave.getFormIndex())) {
odkView.removeWidgetAt(i);
}
}
for (int i = 0; i < questionsAfterSave.length; i++) {
if (!questionsThatHaveNotChanged.contains(questionsAfterSave[i]) && !questionsAfterSave[i].getIndex().equals(lastChangedIndex)) {
// The values of widgets in intent groups are set by the view so widgetValueChanged
// is never called. This means readOnlyOverride can always be set to false.
odkView.addWidgetForQuestion(questionsAfterSave[i], i);
}
}
}
Aggregations