Skip to content

Commit

Permalink
Apply separate style to question text if type is group. (#1546)
Browse files Browse the repository at this point in the history
* Apply style to group type header view.

* Address review comments.

* Address review comment.

* Address review comments.

Co-authored-by: Santosh Pingle <[email protected]>
  • Loading branch information
santosh-pingle and Santosh Pingle authored Aug 26, 2022
1 parent aeb5259 commit b12ff3a
Show file tree
Hide file tree
Showing 9 changed files with 251 additions and 43 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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.views

import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.LinearLayout
import android.widget.TextView
import com.google.android.fhir.datacapture.R
import com.google.android.fhir.datacapture.localizedHintSpanned
import com.google.android.fhir.datacapture.localizedPrefixSpanned
import com.google.android.fhir.datacapture.localizedTextSpanned
import org.hl7.fhir.r4.model.Questionnaire

internal class QuestionnaireGroupTypeHeaderView(context: Context, attrs: AttributeSet?) :
LinearLayout(context, attrs) {

init {
LayoutInflater.from(context).inflate(R.layout.questionnaire_group_type_header, this, true)
}

fun bind(questionnaireItem: Questionnaire.QuestionnaireItemComponent) {
val prefix = findViewById<TextView>(R.id.prefix)
val question = findViewById<TextView>(R.id.question)
val hint = findViewById<TextView>(R.id.hint)
prefix.updateTextAndVisibility(questionnaireItem.localizedPrefixSpanned)
question.updateTextAndVisibility(questionnaireItem.localizedTextSpanned)
hint.updateTextAndVisibility(questionnaireItem.localizedHintSpanned)
visibility = getViewGroupVisibility(prefix, question, hint)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal object QuestionnaireItemGroupViewHolderFactory :
QuestionnaireItemViewHolderFactory(R.layout.questionnaire_item_group_header_view) {
override fun getQuestionnaireItemViewHolderDelegate() =
object : QuestionnaireItemViewHolderDelegate {
private lateinit var header: QuestionnaireItemHeaderView
private lateinit var header: QuestionnaireGroupTypeHeaderView
private lateinit var error: TextView
override lateinit var questionnaireItemViewItem: QuestionnaireItemViewItem

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Google LLC
* 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.
Expand All @@ -17,9 +17,11 @@
package com.google.android.fhir.datacapture.views

import android.content.Context
import android.text.Spanned
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.widget.LinearLayout
import android.widget.TextView
import com.google.android.fhir.datacapture.R
Expand All @@ -41,42 +43,29 @@ internal class QuestionnaireItemHeaderView(context: Context, attrs: AttributeSet
private var hint: TextView = findViewById(R.id.hint)

fun bind(questionnaireItem: Questionnaire.QuestionnaireItemComponent) {
val localizedPrefixSpanned = questionnaireItem.localizedPrefixSpanned
prefix.visibility =
if (localizedPrefixSpanned.isNullOrEmpty()) {
View.GONE
} else {
View.VISIBLE
}
prefix.text = localizedPrefixSpanned

val localizedTextSpanned = questionnaireItem.localizedTextSpanned
question.visibility =
if (localizedTextSpanned.isNullOrEmpty()) {
View.GONE
} else {
View.VISIBLE
}
question.text = localizedTextSpanned

val localizedHintSpanned = questionnaireItem.localizedHintSpanned
hint.visibility =
if (localizedHintSpanned.isNullOrEmpty()) {
View.GONE
} else {
View.VISIBLE
}
hint.text = localizedHintSpanned
prefix.updateTextAndVisibility(questionnaireItem.localizedPrefixSpanned)
question.updateTextAndVisibility(questionnaireItem.localizedTextSpanned)
hint.updateTextAndVisibility(questionnaireItem.localizedHintSpanned)
// Make the entire view GONE if there is nothing to show. This is to avoid an empty row in the
// questionnaire.
visibility =
if (question.visibility == VISIBLE ||
prefix.visibility == VISIBLE ||
hint.visibility == VISIBLE
) {
VISIBLE
} else {
GONE
}
visibility = getViewGroupVisibility(prefix, question, hint)
}
}

internal fun TextView.updateTextAndVisibility(localizedText: Spanned?) {
text = localizedText
visibility =
if (localizedText.isNullOrEmpty()) {
GONE
} else {
VISIBLE
}
}

/** Returns [VISIBLE] if any of the [view] is visible, else returns [GONE]. */
internal fun getViewGroupVisibility(vararg view: TextView): Int {
if (view.any { it.visibility == VISIBLE }) {
return VISIBLE
}
return GONE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8" ?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>

<TextView
android:id="@+id/prefix"
style="?attr/questionnaireGroupTypeQuestionTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="@dimen/prefix_padding_end"
app:layout_constraintEnd_toStartOf="@+id/question"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>

<TextView
android:id="@+id/question"
style="?attr/questionnaireGroupTypeQuestionTextStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/prefix"
app:layout_constraintTop_toTopOf="parent"
/>

<TextView
android:id="@+id/hint"
style="?attr/questionnaireSubtitleTextStyle"
android:text="group type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/question"
/>

</androidx.constraintlayout.widget.ConstraintLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<com.google.android.fhir.datacapture.views.QuestionnaireItemHeaderView
<com.google.android.fhir.datacapture.views.QuestionnaireGroupTypeHeaderView
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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 @@ -17,6 +17,9 @@
<resources>
<!-- Styles for widgets. -->

<!-- Style for group type question text. -->
<attr name="questionnaireGroupTypeQuestionTextStyle" format="reference" />

<!-- Style for question text. -->
<attr name="questionnaireQuestionTextStyle" format="reference" />
<!-- Style for subtitle text. -->
Expand Down
3 changes: 3 additions & 0 deletions datacapture/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
name="Theme.Questionnaire"
parent="Theme.Material3.DayNight.NoActionBar"
>
<item name="questionnaireGroupTypeQuestionTextStyle">
@style/TextAppearance.Material3.TitleMedium
</item>
<item
name="questionnaireQuestionTextStyle"
>@style/TextAppearance.Material3.TitleMedium</item>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* 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.views

import android.view.View
import android.widget.FrameLayout
import android.widget.TextView
import androidx.core.view.isVisible
import com.google.android.fhir.datacapture.R
import com.google.common.truth.Truth.assertThat
import org.hl7.fhir.r4.model.Questionnaire
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment

@RunWith(RobolectricTestRunner::class)
class QuestionnaireGroupTypeHeaderViewTest {
private val parent =
FrameLayout(
RuntimeEnvironment.getApplication().apply { setTheme(R.style.Theme_MaterialComponents) }
)
private val view = QuestionnaireGroupTypeHeaderView(parent.context, null)

@Test
fun shouldShowPrefix() {
view.bind(Questionnaire.QuestionnaireItemComponent().apply { prefix = "Prefix?" })

assertThat(view.findViewById<TextView>(R.id.prefix).isVisible).isTrue()
assertThat(view.findViewById<TextView>(R.id.prefix).text.toString()).isEqualTo("Prefix?")
}

@Test
fun shouldHidePrefix() {
view.bind(Questionnaire.QuestionnaireItemComponent().apply { prefix = "" })

assertThat(view.findViewById<TextView>(R.id.prefix).isVisible).isFalse()
}

@Test
fun shouldShowQuestion() {
view.bind(
Questionnaire.QuestionnaireItemComponent().apply {
repeats = true
text = "Question?"
}
)

assertThat(view.findViewById<TextView>(R.id.question).text.toString()).isEqualTo("Question?")
}

@Test
fun shouldShowHint() {
view.bind(
Questionnaire.QuestionnaireItemComponent().apply {
item =
listOf(
Questionnaire.QuestionnaireItemComponent().apply {
linkId = "nested-display-question"
text = "subtitle text"
type = Questionnaire.QuestionnaireItemType.DISPLAY
}
)
}
)

assertThat(view.findViewById<TextView>(R.id.hint).isVisible).isTrue()
assertThat(view.findViewById<TextView>(R.id.hint).text.toString()).isEqualTo("subtitle text")
}

@Test
fun shouldHideHint() {
view.bind(
Questionnaire.QuestionnaireItemComponent().apply {
item =
listOf(
Questionnaire.QuestionnaireItemComponent().apply {
linkId = "nested-display-question"
type = Questionnaire.QuestionnaireItemType.DISPLAY
}
)
}
)

assertThat(view.findViewById<TextView>(R.id.hint).visibility).isEqualTo(View.GONE)
}

@Test
fun shouldShowHeaderView() {
view.bind(
Questionnaire.QuestionnaireItemComponent().apply {
item =
listOf(
Questionnaire.QuestionnaireItemComponent().apply {
linkId = "nested-display-question"
text = "subtitle text"
type = Questionnaire.QuestionnaireItemType.DISPLAY
}
)
}
)

assertThat(view.visibility).isEqualTo(View.VISIBLE)
}

@Test
fun shouldHideHeaderView() {
view.bind(Questionnaire.QuestionnaireItemComponent())

assertThat(view.visibility).isEqualTo(View.GONE)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class QuestionnaireItemGroupViewHolderFactoryTest {
assertThat(
viewHolder
.itemView
.findViewById<QuestionnaireItemHeaderView>(R.id.header)
.findViewById<QuestionnaireGroupTypeHeaderView>(R.id.header)
.findViewById<TextView>(R.id.hint)
.text
.isNullOrEmpty()
Expand All @@ -128,7 +128,7 @@ class QuestionnaireItemGroupViewHolderFactoryTest {
assertThat(
viewHolder
.itemView
.findViewById<QuestionnaireItemHeaderView>(R.id.header)
.findViewById<QuestionnaireGroupTypeHeaderView>(R.id.header)
.findViewById<TextView>(R.id.hint)
.visibility
)
Expand All @@ -146,7 +146,7 @@ class QuestionnaireItemGroupViewHolderFactoryTest {
)
)
assertThat(
viewHolder.itemView.findViewById<QuestionnaireItemHeaderView>(R.id.header).visibility
viewHolder.itemView.findViewById<QuestionnaireGroupTypeHeaderView>(R.id.header).visibility
)
.isEqualTo(View.VISIBLE)
}
Expand All @@ -163,7 +163,7 @@ class QuestionnaireItemGroupViewHolderFactoryTest {
)

assertThat(
viewHolder.itemView.findViewById<QuestionnaireItemHeaderView>(R.id.header).visibility
viewHolder.itemView.findViewById<QuestionnaireGroupTypeHeaderView>(R.id.header).visibility
)
.isEqualTo(View.GONE)
}
Expand Down

0 comments on commit b12ff3a

Please sign in to comment.