Skip to content

Commit f6983c6

Browse files
committed
Migrate QuantityViewHolderFactory to use Compose
1 parent a4f2e1c commit f6983c6

File tree

5 files changed

+254
-177
lines changed

5 files changed

+254
-177
lines changed

datacapture/src/main/java/com/google/android/fhir/datacapture/extensions/MoreQuestionnaireItemAnswerOptionComponents.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022-2023 Google LLC
2+
* Copyright 2022-2025 Google LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,8 +18,8 @@ package com.google.android.fhir.datacapture.extensions
1818

1919
import android.content.Context
2020
import android.graphics.BitmapFactory
21-
import android.graphics.drawable.BitmapDrawable
2221
import android.graphics.drawable.Drawable
22+
import androidx.core.graphics.drawable.toDrawable
2323
import com.google.android.fhir.datacapture.R
2424
import org.hl7.fhir.r4.model.Attachment
2525
import org.hl7.fhir.r4.model.BooleanType
@@ -63,7 +63,7 @@ fun Questionnaire.QuestionnaireItemAnswerOptionComponent.itemAnswerOptionImage(
6363
val bitmap = BitmapFactory.decodeByteArray(it.data, 0, it.data.size)
6464
val imageSize =
6565
context.resources.getDimensionPixelOffset(R.dimen.item_answer_media_image_size)
66-
val drawable: Drawable = BitmapDrawable(context.resources, bitmap)
66+
val drawable: Drawable = bitmap.toDrawable(context.resources)
6767
drawable.setBounds(0, 0, imageSize, imageSize)
6868
drawable
6969
}

datacapture/src/main/java/com/google/android/fhir/datacapture/views/compose/EditTextFieldItem.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import androidx.compose.foundation.text.KeyboardOptions
2323
import androidx.compose.material3.Icon
2424
import androidx.compose.material3.MaterialTheme
2525
import androidx.compose.material3.OutlinedTextField
26-
import androidx.compose.material3.OutlinedTextFieldDefaults
2726
import androidx.compose.material3.Text
2827
import androidx.compose.runtime.Composable
2928
import androidx.compose.runtime.LaunchedEffect
@@ -119,7 +118,6 @@ internal fun OutlinedEditTextFieldItem(
119118
label = { hint?.let { Text(it) } },
120119
supportingText = { helperText?.let { Text(it) } },
121120
isError = isError,
122-
colors = OutlinedTextFieldDefaults.colors(),
123121
trailingIcon = {
124122
if (isError) {
125123
Icon(painter = painterResource(R.drawable.error_24px), contentDescription = "Error")
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.android.fhir.datacapture.views.compose
18+
19+
import androidx.compose.material3.DropdownMenuItem
20+
import androidx.compose.material3.ExperimentalMaterial3Api
21+
import androidx.compose.material3.ExposedDropdownMenuBox
22+
import androidx.compose.material3.ExposedDropdownMenuDefaults
23+
import androidx.compose.material3.Icon
24+
import androidx.compose.material3.MaterialTheme
25+
import androidx.compose.material3.MenuAnchorType
26+
import androidx.compose.material3.OutlinedTextField
27+
import androidx.compose.material3.Text
28+
import androidx.compose.runtime.Composable
29+
import androidx.compose.runtime.LaunchedEffect
30+
import androidx.compose.runtime.derivedStateOf
31+
import androidx.compose.runtime.getValue
32+
import androidx.compose.runtime.mutableStateOf
33+
import androidx.compose.runtime.remember
34+
import androidx.compose.runtime.setValue
35+
import androidx.compose.ui.Modifier
36+
import androidx.compose.ui.graphics.asImageBitmap
37+
import androidx.core.graphics.drawable.toBitmap
38+
import com.google.android.fhir.datacapture.views.factories.DropDownAnswerOption
39+
40+
@OptIn(ExperimentalMaterial3Api::class)
41+
@Composable
42+
internal fun ExposedDropDownMenuBoxItem(
43+
modifier: Modifier,
44+
enabled: Boolean,
45+
selectedOption: DropDownAnswerOption? = null,
46+
options: List<DropDownAnswerOption>,
47+
onDropDownAnswerOptionSelected: (DropDownAnswerOption?) -> Unit,
48+
) {
49+
var expanded by remember { mutableStateOf(false) }
50+
var selectedDropDownAnswerOption by
51+
remember(selectedOption, options) { mutableStateOf(selectedOption) }
52+
val selectedOptionDisplay by remember {
53+
derivedStateOf { selectedDropDownAnswerOption?.answerOptionString ?: "" }
54+
}
55+
56+
LaunchedEffect(selectedDropDownAnswerOption) {
57+
onDropDownAnswerOptionSelected(selectedDropDownAnswerOption)
58+
}
59+
60+
ExposedDropdownMenuBox(
61+
modifier = modifier,
62+
expanded = expanded,
63+
onExpandedChange = { expanded = it },
64+
) {
65+
OutlinedTextField(
66+
value = selectedOptionDisplay,
67+
onValueChange = {},
68+
modifier = Modifier.menuAnchor(MenuAnchorType.PrimaryNotEditable, enabled),
69+
readOnly = true,
70+
enabled = enabled,
71+
minLines = 1,
72+
label = {},
73+
supportingText = {},
74+
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
75+
)
76+
ExposedDropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
77+
options.forEach { option ->
78+
DropdownMenuItem(
79+
text = {
80+
Text(option.answerOptionAnnotatedString(), style = MaterialTheme.typography.bodyLarge)
81+
},
82+
leadingIcon = {
83+
option.answerOptionImage?.let {
84+
Icon(
85+
it.toBitmap().asImageBitmap(),
86+
contentDescription = option.answerOptionString,
87+
)
88+
}
89+
},
90+
enabled = enabled,
91+
onClick = {
92+
selectedDropDownAnswerOption = option
93+
expanded = false
94+
},
95+
contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
96+
)
97+
}
98+
}
99+
}
100+
}

datacapture/src/main/java/com/google/android/fhir/datacapture/views/factories/DropDownViewHolderFactory.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import com.google.android.fhir.datacapture.extensions.getValidationErrorMessage
3838
import com.google.android.fhir.datacapture.extensions.identifierString
3939
import com.google.android.fhir.datacapture.extensions.itemAnswerOptionImage
4040
import com.google.android.fhir.datacapture.extensions.localizedFlyoverSpanned
41+
import com.google.android.fhir.datacapture.extensions.toAnnotatedString
4142
import com.google.android.fhir.datacapture.extensions.toSpanned
4243
import com.google.android.fhir.datacapture.extensions.tryUnwrapContext
4344
import com.google.android.fhir.datacapture.validation.ValidationResult
@@ -213,4 +214,6 @@ internal data class DropDownAnswerOption(
213214
}
214215

215216
fun answerOptionStringSpanned(): Spanned = answerOptionString.toSpanned()
217+
218+
fun answerOptionAnnotatedString() = answerOptionString.toAnnotatedString()
216219
}

0 commit comments

Comments
 (0)