@@ -21,7 +21,6 @@ import android.os.Bundle
21
21
import android.view.LayoutInflater
22
22
import android.view.View
23
23
import android.view.ViewGroup
24
- import android.widget.Button
25
24
import androidx.annotation.VisibleForTesting
26
25
import androidx.appcompat.view.ContextThemeWrapper
27
26
import androidx.core.content.res.use
@@ -34,6 +33,7 @@ import androidx.lifecycle.lifecycleScope
34
33
import androidx.recyclerview.widget.LinearLayoutManager
35
34
import androidx.recyclerview.widget.RecyclerView
36
35
import com.google.android.fhir.datacapture.validation.Invalid
36
+ import com.google.android.fhir.datacapture.views.NavigationViewHolder
37
37
import com.google.android.fhir.datacapture.views.factories.QuestionnaireItemViewHolderFactory
38
38
import com.google.android.material.progressindicator.LinearProgressIndicator
39
39
import kotlinx.coroutines.launch
@@ -94,58 +94,44 @@ class QuestionnaireFragment : Fragment() {
94
94
view.findViewById<RecyclerView >(R .id.questionnaire_edit_recycler_view)
95
95
val questionnaireReviewRecyclerView =
96
96
view.findViewById<RecyclerView >(R .id.questionnaire_review_recycler_view)
97
- val paginationPreviousButton = view.findViewById<View >(R .id.pagination_previous_button)
98
- paginationPreviousButton.setOnClickListener { viewModel.goToPreviousPage() }
99
- val paginationNextButton = view.findViewById<View >(R .id.pagination_next_button)
100
- paginationNextButton.setOnClickListener { viewModel.goToNextPage() }
101
- view.findViewById<Button >(R .id.cancel_questionnaire).setOnClickListener {
97
+
98
+ // This container frame floats at the bottom of the view to make navigation controls visible at
99
+ // all times when the user scrolls. Use
100
+ // [QuestionnaireFragment.Builder.setShowNavigationInDefaultLongScroll] to disable this.
101
+ val bottomNavContainerFrame = view.findViewById<View >(R .id.bottom_nav_container_frame)
102
+
103
+ viewModel.setOnCancelButtonClickListener {
102
104
QuestionnaireCancelDialogFragment ()
103
105
.show(requireActivity().supportFragmentManager, QuestionnaireCancelDialogFragment .TAG )
104
106
}
105
-
106
- view
107
- .findViewById<Button >(R .id.submit_questionnaire)
108
- .apply {
109
- text =
110
- requireArguments()
111
- .getString(EXTRA_SUBMIT_BUTTON_TEXT , getString(R .string.submit_questionnaire))
112
- }
113
- .setOnClickListener {
114
- lifecycleScope.launch {
115
- viewModel.validateQuestionnaireAndUpdateUI().let { validationMap ->
116
- if (validationMap.values.flatten().filterIsInstance<Invalid >().isEmpty()) {
117
- setFragmentResult(SUBMIT_REQUEST_KEY , Bundle .EMPTY )
118
- } else {
119
- val errorViewModel: QuestionnaireValidationErrorViewModel by activityViewModels()
120
- errorViewModel.setQuestionnaireAndValidation(viewModel.questionnaire, validationMap)
121
- QuestionnaireValidationErrorMessageDialogFragment ()
122
- .show(
123
- requireActivity().supportFragmentManager,
124
- QuestionnaireValidationErrorMessageDialogFragment .TAG ,
125
- )
126
- }
107
+ viewModel.setOnSubmitButtonClickListener {
108
+ lifecycleScope.launch {
109
+ viewModel.validateQuestionnaireAndUpdateUI().let { validationMap ->
110
+ if (validationMap.values.flatten().filterIsInstance<Invalid >().isEmpty()) {
111
+ setFragmentResult(SUBMIT_REQUEST_KEY , Bundle .EMPTY )
112
+ } else {
113
+ val errorViewModel: QuestionnaireValidationErrorViewModel by activityViewModels()
114
+ errorViewModel.setQuestionnaireAndValidation(viewModel.questionnaire, validationMap)
115
+ QuestionnaireValidationErrorMessageDialogFragment ()
116
+ .show(
117
+ requireActivity().supportFragmentManager,
118
+ QuestionnaireValidationErrorMessageDialogFragment .TAG ,
119
+ )
127
120
}
128
121
}
129
122
}
123
+ }
130
124
val questionnaireProgressIndicator: LinearProgressIndicator =
131
125
view.findViewById(R .id.questionnaire_progress_indicator)
132
126
val questionnaireEditAdapter =
133
127
QuestionnaireEditAdapter (questionnaireItemViewHolderFactoryMatchersProvider.get())
134
128
val questionnaireReviewAdapter = QuestionnaireReviewAdapter ()
135
129
136
- val submitButton = requireView().findViewById<Button >(R .id.submit_questionnaire)
137
- val cancelButton = requireView().findViewById<Button >(R .id.cancel_questionnaire)
138
-
139
130
val reviewModeEditButton =
140
131
view.findViewById<View >(R .id.review_mode_edit_button).apply {
141
132
setOnClickListener { viewModel.setReviewMode(false ) }
142
133
}
143
134
144
- val reviewModeButton =
145
- view.findViewById<View >(R .id.review_mode_button).apply {
146
- setOnClickListener { viewModel.setReviewMode(true ) }
147
- }
148
-
149
135
questionnaireEditRecyclerView.adapter = questionnaireEditAdapter
150
136
val linearLayoutManager = LinearLayoutManager (view.context)
151
137
questionnaireEditRecyclerView.layoutManager = linearLayoutManager
@@ -163,23 +149,20 @@ class QuestionnaireFragment : Fragment() {
163
149
// Set items
164
150
questionnaireEditRecyclerView.visibility = View .GONE
165
151
questionnaireReviewAdapter.submitList(
166
- state.items.filterIsInstance< QuestionnaireAdapterItem . Question >() ,
152
+ state.items,
167
153
)
168
154
questionnaireReviewRecyclerView.visibility = View .VISIBLE
169
-
170
- // Set button visibility
171
- submitButton.visibility = if (displayMode.showSubmitButton) View .VISIBLE else View .GONE
172
- cancelButton.visibility = if (displayMode.showCancelButton) View .VISIBLE else View .GONE
173
-
174
- reviewModeButton.visibility = View .GONE
175
155
reviewModeEditButton.visibility =
176
156
if (displayMode.showEditButton) {
177
157
View .VISIBLE
178
158
} else {
179
159
View .GONE
180
160
}
181
- paginationPreviousButton.visibility = View .GONE
182
- paginationNextButton.visibility = View .GONE
161
+
162
+ // Set bottom navigation
163
+ bottomNavContainerFrame.visibility = View .VISIBLE
164
+ NavigationViewHolder (bottomNavContainerFrame)
165
+ .bind(state.bottomNavItems.single().questionnaireNavigationUIState)
183
166
184
167
// Hide progress indicator
185
168
questionnaireProgressIndicator.visibility = View .GONE
@@ -189,25 +172,12 @@ class QuestionnaireFragment : Fragment() {
189
172
questionnaireReviewRecyclerView.visibility = View .GONE
190
173
questionnaireEditAdapter.submitList(state.items)
191
174
questionnaireEditRecyclerView.visibility = View .VISIBLE
192
-
193
- // Set button visibility
194
- submitButton.visibility =
195
- if (displayMode.pagination.showSubmitButton) View .VISIBLE else View .GONE
196
- cancelButton.visibility =
197
- if (displayMode.pagination.showCancelButton) View .VISIBLE else View .GONE
198
- reviewModeButton.visibility =
199
- if (displayMode.pagination.showReviewButton) View .VISIBLE else View .GONE
200
175
reviewModeEditButton.visibility = View .GONE
201
176
202
- if (displayMode.pagination.isPaginated) {
203
- paginationPreviousButton.visibility =
204
- if (displayMode.pagination.hasPreviousPage) View .VISIBLE else View .GONE
205
- paginationNextButton.visibility =
206
- if (displayMode.pagination.hasNextPage) View .VISIBLE else View .GONE
207
- } else {
208
- paginationPreviousButton.visibility = View .GONE
209
- paginationNextButton.visibility = View .GONE
210
- }
177
+ // Set bottom navigation
178
+ bottomNavContainerFrame.visibility = View .VISIBLE
179
+ NavigationViewHolder (bottomNavContainerFrame)
180
+ .bind(state.bottomNavItems.single().questionnaireNavigationUIState)
211
181
212
182
// Set progress indicator
213
183
questionnaireProgressIndicator.visibility = View .VISIBLE
@@ -241,13 +211,9 @@ class QuestionnaireFragment : Fragment() {
241
211
is DisplayMode .InitMode -> {
242
212
questionnaireReviewRecyclerView.visibility = View .GONE
243
213
questionnaireEditRecyclerView.visibility = View .GONE
244
- paginationPreviousButton.visibility = View .GONE
245
- paginationNextButton.visibility = View .GONE
246
214
questionnaireProgressIndicator.visibility = View .GONE
247
- submitButton.visibility = View .GONE
248
- cancelButton.visibility = View .GONE
249
- reviewModeButton.visibility = View .GONE
250
215
reviewModeEditButton.visibility = View .GONE
216
+ bottomNavContainerFrame.visibility = View .GONE
251
217
}
252
218
}
253
219
}
@@ -425,6 +391,14 @@ class QuestionnaireFragment : Fragment() {
425
391
*/
426
392
fun setShowCancelButton (value : Boolean ) = apply { args.add(EXTRA_SHOW_CANCEL_BUTTON to value) }
427
393
394
+ /* *
395
+ * A [Boolean] extra to show questionnaire page as a default/long scroll with the
396
+ * previous/next/submit buttons anchored to bottom/end of page. Default is false.
397
+ */
398
+ fun setShowNavigationInDefaultLongScroll (value : Boolean ) = apply {
399
+ args.add(EXTRA_SHOW_NAVIGATION_IN_DEFAULT_LONG_SCROLL to value)
400
+ }
401
+
428
402
@VisibleForTesting fun buildArgs () = bundleOf(* args.toTypedArray())
429
403
430
404
/* * @return A [QuestionnaireFragment] with provided [Bundle] arguments. */
@@ -524,6 +498,9 @@ class QuestionnaireFragment : Fragment() {
524
498
525
499
internal const val EXTRA_SUBMIT_BUTTON_TEXT = " submit-button-text"
526
500
501
+ internal const val EXTRA_SHOW_NAVIGATION_IN_DEFAULT_LONG_SCROLL =
502
+ " show-navigation-in-default-long-scroll"
503
+
527
504
fun builder () = Builder ()
528
505
}
529
506
0 commit comments