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

Improve Dropdown Behavior in Questionnaire Items #2393

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
24404bb
- Make the dropdown non-editable after an option is selected.
qaziabubakar-vd Dec 29, 2023
730cd1b
Show the dropdown once the text is deleted
qaziabubakar-vd Jan 3, 2024
5094e49
Merge branch 'master' into issue-2228-dropdown-non-editable
qaziabubakar-vd Jan 8, 2024
caeae47
Spotless Apply
qaziabubakar-vd Jan 8, 2024
9e30f45
Merge remote-tracking branch 'origin/issue-2228-dropdown-non-editable…
qaziabubakar-vd Jan 8, 2024
3bead63
Merge branch 'master' into issue-2228-dropdown-non-editable
f-odhiambo Jan 15, 2024
a6959c6
Merge branch 'master' into issue-2228-dropdown-non-editable
jingtang10 Feb 6, 2024
dd3ead3
Update datacapture/src/main/java/com/google/android/fhir/datacapture/…
qaziabubakar-vd Feb 26, 2024
d5d7355
Update header_view.xml according to the new design
qaziabubakar-vd Feb 26, 2024
916829e
Merge remote-tracking branch 'origin/issue-2228-dropdown-non-editable…
qaziabubakar-vd Feb 26, 2024
6fbdf2e
Merge branch 'master' into issue-2228-dropdown-non-editable
qaziabubakar-vd Feb 26, 2024
d6bf618
Update DropDownViewHolderFactory
qaziabubakar-vd Feb 26, 2024
ebdfb28
Merge branch 'master' into issue-2228-dropdown-non-editable
qaziabubakar-vd Feb 26, 2024
d6a4545
Update DropDownViewHolderFactory to have a clear icon once the option…
qaziabubakar-vd Feb 26, 2024
c1daa30
Update when the clearIcon is enabled
qaziabubakar-vd Mar 15, 2024
7bb2776
Update clearIcon visibility based on the readOnly property
qaziabubakar-vd Mar 15, 2024
32cb079
clear answer from the questionnaireViewItem when the user taps on the…
qaziabubakar-vd Mar 15, 2024
c9baa38
Add new tests
qaziabubakar-vd Mar 18, 2024
36d16fc
Add new code comments
qaziabubakar-vd Mar 18, 2024
a35e0a7
Merge remote-tracking branch 'Android-FHIR/master' into issue-2228-dr…
qaziabubakar-vd Mar 18, 2024
36a1806
Resolve conflicts
qaziabubakar-vd Mar 18, 2024
b305bb0
Merge branch 'master' into issue-2228-dropdown-non-editable
qaziabubakar-vd Mar 19, 2024
7e68464
Merge branch 'master' into issue-2228-dropdown-non-editable
dubdabasoduba Oct 23, 2024
dd187c3
Merge branch 'master' of github.com:google/android-fhir into issue-22…
FikriMilano Jan 28, 2025
a994dc3
Refactor implementation
FikriMilano Jan 28, 2025
fcf841e
Move clearInputIcon click listener to init function
FikriMilano Jan 28, 2025
12fb10b
Show dropdown once answer is cleared
FikriMilano Jan 28, 2025
d840f61
Remove ripple effect on clear icon
FikriMilano Jan 29, 2025
041d121
Add tests
FikriMilano Jan 29, 2025
c811179
spotless
FikriMilano Jan 29, 2025
3d1149b
Merge branch 'master' of github.com:google/android-fhir into issue-22…
FikriMilano Jan 29, 2025
00d235c
Rename test components
FikriMilano Jan 29, 2025
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
@@ -1,5 +1,5 @@
/*
* Copyright 2022-2023 Google LLC
* Copyright 2022-2024 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 @@ -18,12 +18,18 @@ package com.google.android.fhir.datacapture.views.factories

import android.content.Context
import android.graphics.drawable.Drawable
import android.os.Handler
import android.os.Looper
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import androidx.core.widget.doAfterTextChanged
import com.google.android.fhir.datacapture.R
import com.google.android.fhir.datacapture.extensions.displayString
import com.google.android.fhir.datacapture.extensions.getRequiredOrOptionalText
Expand All @@ -46,13 +52,16 @@ internal object DropDownViewHolderFactory :
private lateinit var header: HeaderView
private lateinit var textInputLayout: TextInputLayout
private lateinit var autoCompleteTextView: MaterialAutoCompleteTextView
private lateinit var clearIcon: ImageView
override lateinit var questionnaireViewItem: QuestionnaireViewItem
private lateinit var context: Context
private var isDropdownEditable = true
qaziabubakar-vd marked this conversation as resolved.
Show resolved Hide resolved
qaziabubakar-vd marked this conversation as resolved.
Show resolved Hide resolved

override fun init(itemView: View) {
header = itemView.findViewById(R.id.header)
textInputLayout = itemView.findViewById(R.id.text_input_layout)
autoCompleteTextView = itemView.findViewById(R.id.auto_complete)
clearIcon = itemView.findViewById(R.id.clearIcon)
context = itemView.context
}

Expand Down Expand Up @@ -97,32 +106,58 @@ internal object DropDownViewHolderFactory :
null,
)
}

autoCompleteTextView.setAdapter(adapter)
autoCompleteTextView.onItemClickListener =
AdapterView.OnItemClickListener { _, _, position, _ ->
val selectedItem = adapter.getItem(position)
autoCompleteTextView.setText(selectedItem?.answerOptionString, false)
autoCompleteTextView.setCompoundDrawablesRelative(
adapter.getItem(position)?.answerOptionImage,
null,
null,
null,
)
val selectedAnswer =
questionnaireViewItem.enabledAnswerOptions
.firstOrNull { it.value.identifierString(context) == selectedItem?.answerId }
?.value

if (selectedAnswer == null) {
questionnaireViewItem.clearAnswer()
} else {
questionnaireViewItem.setAnswer(
QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent()
.setValue(selectedAnswer),
if (isDropdownEditable) {
qaziabubakar-vd marked this conversation as resolved.
Show resolved Hide resolved
val selectedItem = adapter.getItem(position)
autoCompleteTextView.setText(selectedItem?.answerOptionString, false)
autoCompleteTextView.setCompoundDrawablesRelative(
adapter.getItem(position)?.answerOptionImage,
null,
null,
null,
)

isDropdownEditable = false
val selectedAnswer =
questionnaireViewItem.enabledAnswerOptions
.firstOrNull { it.value.identifierString(context) == selectedItem?.answerId }
?.value

if (selectedAnswer == null) {
questionnaireViewItem.clearAnswer()
} else {
questionnaireViewItem.setAnswer(
QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent()
.setValue(selectedAnswer),
)
}
}
}

autoCompleteTextView.doAfterTextChanged {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't know if you can use draft answer here... try to set draft answer and reset the widget? i guess one problem might be the cursor moving? @aditya-07 do you have experience with this?

if (it.isNullOrBlank()) {
clearIcon.visibility = View.GONE
autoCompleteTextView.postDelayed(
{
if (autoCompleteTextView.isPopupShowing.not() && isDropdownEditable) {
qaziabubakar-vd marked this conversation as resolved.
Show resolved Hide resolved
autoCompleteTextView.showDropDown()
}
}, 100
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a way to avoid using this delay? why is it here? can you add some comments?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use several other implementation, using the setOnDismissListener as well but the internal mechanism of the MaterialAutoCompleteTextView is such that it resets the view when the text get cleared.
Our implementation should have been a straight forward one that when the text is cleared we display the dropdown but MaterialAutoCompleteTextView resets its state every time the text gets cleared.
I will also put some comments here.

)
} else {
clearIcon.visibility = View.VISIBLE
}
}

clearIcon.setOnClickListener {
autoCompleteTextView.text = null
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't you have to clear the answer in the questionnaire view item too?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I have added this here, now when the user taps on the clearIcon, I call the questionnaireViewItem.clearAnswer() as well.

isDropdownEditable = true
setReadOnly(false)
qaziabubakar-vd marked this conversation as resolved.
Show resolved Hide resolved
}

displayValidationResult(questionnaireViewItem.validationResult)
}

Expand All @@ -137,6 +172,7 @@ internal object DropDownViewHolderFactory :

override fun setReadOnly(isReadOnly: Boolean) {
textInputLayout.isEnabled = !isReadOnly
autoCompleteTextView.isEnabled = isDropdownEditable
qaziabubakar-vd marked this conversation as resolved.
Show resolved Hide resolved
}

private fun cleanupOldState() {
Expand Down
12 changes: 12 additions & 0 deletions datacapture/src/main/res/drawable/ic_clear.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="24"
android:viewportHeight="24"
>
<path
android:fillColor="#999999"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"
/>
</vector>
36 changes: 28 additions & 8 deletions datacapture/src/main/res/layout/drop_down_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/item_margin_horizontal"
Expand All @@ -32,21 +33,40 @@
android:layout_height="wrap_content"
/>

<com.google.android.material.textfield.TextInputLayout
style="?attr/questionnaireDropdownLayoutStyle"
android:id="@+id/text_input_layout"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>

<com.google.android.material.textfield.MaterialAutoCompleteTextView
style="?attr/questionnaireDropDownSelectedTextStyle"
android:id="@+id/auto_complete"
android:drawablePadding="@dimen/icon_drawable_padding"
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/text_input_layout"
style="?attr/questionnaireDropdownLayoutStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>

<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/auto_complete"
style="?attr/questionnaireDropDownSelectedTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawablePadding="@dimen/icon_drawable_padding"
/>

</com.google.android.material.textfield.TextInputLayout>

<ImageView
android:id="@+id/clearIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:layout_marginTop="@dimen/help_container_margin_top"
android:layout_marginEnd="@dimen/drop_down_clear_icon_margin"
android:padding="@dimen/icon_drawable_padding"
android:src="@drawable/ic_clear"
android:visibility="gone"
/>

</com.google.android.material.textfield.TextInputLayout>
</FrameLayout>

</LinearLayout>
1 change: 1 addition & 0 deletions datacapture/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@

<!-- Dropdown -->
<dimen name="drop_down_padding">16dp</dimen>
<dimen name="drop_down_clear_icon_margin">28dp</dimen>

<!-- Item Answer Media -->
<dimen name="item_answer_media_image_size">48dp</dimen>
Expand Down
Loading