Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDC: Add Progress Bar for Questionnaire #1587

Merged
merged 18 commits into from
Oct 18, 2022
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
67aea0f
Added Linear Progress Indicator for Paginated Questionnaire
nsabale7 Sep 6, 2022
853595b
Added Linear Progress Indicator for Non-Paginated Questionnaire
nsabale7 Sep 8, 2022
96ee4f0
Removed print statement
nsabale7 Sep 8, 2022
ae581d6
Added style for linear progressIndicator
nsabale7 Sep 9, 2022
3160aaf
Merge branch 'master' of https://github.com/google/android-fhir into …
nsabale7 Sep 16, 2022
3b6029c
Merge branch 'master' of https://github.com/google/android-fhir into …
nsabale7 Sep 28, 2022
6742331
Tests to scroll default and navigate paginated questionnaire
nsabale7 Sep 29, 2022
89c0632
Renamed MainActivityTest to LayoutsFragmentTest
nsabale7 Sep 29, 2022
f691eff
Merge branch 'master' of https://github.com/google/android-fhir into …
nsabale7 Sep 29, 2022
0c63075
Removed tests for scroll behaviour from catalog module
nsabale7 Oct 3, 2022
2e34a8d
Merge branch 'master' of https://github.com/google/android-fhir into …
nsabale7 Oct 3, 2022
77c24ff
Merge branch 'master' into ns/progress_bar_for_questionnaires
nsabale7 Oct 7, 2022
c344f67
Merge branch 'master' of https://github.com/google/android-fhir into …
nsabale7 Oct 15, 2022
baa9e61
Changes as per JT feedback
nsabale7 Oct 18, 2022
44f2549
Merge branch 'master' of https://github.com/google/android-fhir into …
nsabale7 Oct 18, 2022
b651a6a
Moved progress percentage calculation to QuestionnaireFragment
nsabale7 Oct 18, 2022
7968128
Update datacapture/src/main/java/com/google/android/fhir/datacapture/…
jingtang10 Oct 18, 2022
481ea43
Merge branch 'master' into ns/progress_bar_for_questionnaires
jingtang10 Oct 18, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.fhir.datacapture.utilities.calculatePercent
import com.google.android.fhir.datacapture.views.QuestionnaireItemViewHolderFactory
import com.google.android.material.progressindicator.LinearProgressIndicator
import org.hl7.fhir.r4.model.Questionnaire

/**
Expand Down Expand Up @@ -76,6 +78,8 @@ open class QuestionnaireFragment : Fragment() {
requireView().findViewById<Button>(R.id.submit_questionnaire).setOnClickListener {
setFragmentResult(SUBMIT_REQUEST_KEY, Bundle.EMPTY)
}
val questionnaireProgressIndicator: LinearProgressIndicator =
view.findViewById(R.id.questionnaire_progress_indicator)
val questionnaireItemEditAdapter =
QuestionnaireItemEditAdapter(getCustomQuestionnaireItemViewHolderFactoryMatchers())
val questionnaireItemReviewAdapter = QuestionnaireItemReviewAdapter()
Expand All @@ -93,7 +97,8 @@ open class QuestionnaireFragment : Fragment() {
reviewModeButton.setOnClickListener { viewModel.setReviewMode(true) }

questionnaireEditRecyclerView.adapter = questionnaireItemEditAdapter
questionnaireEditRecyclerView.layoutManager = LinearLayoutManager(view.context)
val linearLayoutManager = LinearLayoutManager(view.context)
questionnaireEditRecyclerView.layoutManager = linearLayoutManager
// Animation does work well with views that could gain focus
questionnaireEditRecyclerView.itemAnimator = null

Expand All @@ -108,21 +113,47 @@ open class QuestionnaireFragment : Fragment() {
questionnaireReviewRecyclerView.visibility = View.VISIBLE
questionnaireEditRecyclerView.visibility = View.GONE
reviewModeEditButton.visibility = View.VISIBLE
questionnaireProgressIndicator.visibility = View.GONE
} else {
questionnaireItemEditAdapter.submitList(state.items)
questionnaireEditRecyclerView.visibility = View.VISIBLE
questionnaireReviewRecyclerView.visibility = View.GONE
reviewModeEditButton.visibility = View.GONE
questionnaireProgressIndicator.visibility = View.VISIBLE
}

if (state.pagination.isPaginated && !state.reviewMode) {
paginationPreviousButton.visibility = View.VISIBLE
paginationPreviousButton.isEnabled = state.pagination.hasPreviousPage
paginationNextButton.visibility = View.VISIBLE
paginationNextButton.isEnabled = state.pagination.hasNextPage
questionnaireProgressIndicator.updateProgressIndicator(
calculatePercent(
count =
(state.pagination.currentPageIndex +
1), // incremented by 1 due to initialPageIndex starts with 0.
totalCount = state.pagination.pages.size
)
)
} else {
paginationPreviousButton.visibility = View.GONE
paginationNextButton.visibility = View.GONE

questionnaireEditRecyclerView.addOnScrollListener(
object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
questionnaireProgressIndicator.updateProgressIndicator(
calculatePercent(
count =
(linearLayoutManager.findLastVisibleItemPosition() +
1), // incremented by 1 due to findLastVisiblePosition() starts with 0.
totalCount = linearLayoutManager.itemCount
)
)
}
}
)
}

reviewModeButton.visibility =
Expand Down Expand Up @@ -233,3 +264,14 @@ open class QuestionnaireFragment : Fragment() {
val matches: (Questionnaire.QuestionnaireItemComponent) -> Boolean,
)
}
/**
* Updates the [LinearProgressIndicator] progress with given value.
*
* This method will also set max value of [LinearProgressIndicator] to 100.
*
* @param progress The new progress [Integer] value between 0 to 100.
*/
internal fun LinearProgressIndicator.updateProgressIndicator(progress: Int) {
setProgress(progress)
max = 100
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.android.fhir.datacapture.utilities

/** Calculates the percentage from given [count] and [totalCount] values. */
internal fun calculatePercent(count: Int, totalCount: Int): Int {
return if (totalCount == 0) 0 else (count * 100 / totalCount)
}
13 changes: 12 additions & 1 deletion datacapture/src/main/res/layout/questionnaire_fragment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,24 @@
app:layout_constraintTop_toTopOf="parent"
/>

<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/questionnaire_progress_indicator"
style="?attr/questionnaireLinearProgressIndicatorStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/review_mode_edit_button"
app:layout_constraintBottom_toTopOf="@id/questionnaire_edit_recycler_view"
/>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/questionnaire_edit_recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toTopOf="@+id/bottom_buttons"
app:layout_constraintTop_toBottomOf="@+id/review_mode_edit_button"
app:layout_constraintTop_toBottomOf="@+id/questionnaire_progress_indicator"
/>

<androidx.recyclerview.widget.RecyclerView
Expand Down
3 changes: 3 additions & 0 deletions datacapture/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@
<!-- Style for edit button. -->
<attr name="questionnaireEditButtonStyle" format="reference" />

<!-- Style for Linear Progress Indicator. -->
<attr name="questionnaireLinearProgressIndicatorStyle" format="reference" />

<declare-styleable name="QuestionnaireTheme">
<!-- The ID of the theme to be applied to the questionnaire. The referenced theme must
extend Theme.Questionnaire. If unspecified, Theme.Questionnaire will be used. -->
Expand Down
4 changes: 4 additions & 0 deletions datacapture/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@
name="questionnaireAddAnotherAnswerButtonStyle"
>@style/Widget.Material3.Button
</item>
<item
name="questionnaireLinearProgressIndicatorStyle"
>@style/Widget.Material3.LinearProgressIndicator
</item>
</style>

<style
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.android.fhir.datacapture.utilities

import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner

@RunWith(RobolectricTestRunner::class)
class MoreNumberUtilTest {

@Test
fun `calculatePercent should return zero for totalCount as zero`() {
assertThat(calculatePercent(count = 10, totalCount = 0)).isEqualTo(0)
}

@Test
fun `calculatePercent should return valid result`() {
assertThat(calculatePercent(count = 10, totalCount = 50)).isEqualTo(20)
}
}