Hello I'm attempting to implement a custom text f...
# compose
g
Hello I'm attempting to implement a custom text field (see screenshot) with some specific accessibility requirements for talkback. The designers want to have talkback read out the field as the labels above the field then the text field info. So in the screenshot example would be "Favourite airline. You must have travelled with them in the last 5 years. EditText. Double tap to edit" Also have the entire component considered as a single unit on talkback so the user would be able to select it as one rather than individual fields. However regardless what I try I can only get with the text field info first i.e "EditText. Favourite airline. You must have travelled with them in the last 5 years. Double tap to edit" I've put a heavily condensed version in the thread. My assumption is that as the actual EditText field is focusable so talkback reads that out first but I may be wrong. Does anyone have any ideas of different approaches or any insights?
Copy code
@Composable
fun CustomTexField() {
    Column(modifier = Modifier) {
        var value by remember { mutableStateOf("") }
        BasicTextField2(
            value = value,
            onValueChange = { value = it },
            decorator = {
                TextFieldDecorator(textFieldContent = it,)
            })
    }
}

@Composable
private fun TextFieldDecorator(
    modifier: Modifier = Modifier,
    textFieldContent: @Composable () -> Unit,
) {
    Column(modifier = modifier) {
        Text(text = "Favourite Airline")
        Text(text = "You must have travelled with them in the last five years")
        Row {
            textFieldContent()
        }
    }
}
a
I am not getting your code do compile as is.
Cant you use
mergeDescendants =true
to handle this?
g
Sorry for the late reply What error did you get? I think it should compile if you add all the imports in and experimental annotations. I don't think merge descendants works in this scenario as I effectively want to change the order of what is read out by default. I found out it would read the following order 1. BasicTextField role/ state - "Edit box" when empty and "Editing, <content of text field>", Edit box" when there is content 2. Any content description on the TextFieldDecorator : "Favourite Airline" etc - 3. Hint = "Double tap to edit" The request from my designer was to see if it was possible to swap the order of 2 and 1 Does that make sense? But it looks like that is not customisable at all but they are happy with that.
a
Neither
BasicTextField2
nor
BasicTextField
resolves properly
image.png
g
Ah right, It was the specific version of compose I was using.
Copy code
@Composable
fun CustomTexField() {
    Column(modifier = Modifier) {
        val state = rememberTextFieldState()
        BasicTextField(
            state = state,
            decorator = {
                TextFieldDecorator(textFieldContent = it,)
            })
    }
}

@Composable
private fun TextFieldDecorator(
    modifier: Modifier = Modifier,
    textFieldContent: @Composable () -> Unit,
) {
    Column(modifier = modifier) {
        Text(text = "Favourite Airline")
        Text(text = "You must have travelled with them in the last five years")
        Row {
            textFieldContent()
        }
    }
}
BasicEditText2 was removed after 1.7.1 I think
a
Maybe replace
decorator
with
decorationBox
But anyhow I do think the whole purpose of decorator is to have that label as a descriptor for the Editbox. We have a similar setup in our code and “Edittext” is also read first. I do think your designer might have it wrong and may be unfamiliar with how androids Talkback is supposed to work? If you look into “advanced settings” for Talkback a user can set their preferred order to be consistent throughtout the whole phone UI.
g
Yes I had said that was the default way and they were happy enough, I'm also learning about talkback a lot as well. Thanks I did not realise it was possible to customise that. I will let them know.
👍 1