How to make talkback read out Text and switch together in Android?

70 Views Asked by At

Hello I am trying to make talkback read out text from Text() and default line from Switch() using compose semantics. This is my code:

var toggle by remember {
                mutableStateOf(true)
            }
            Column(
                modifier = Modifier.fillMaxSize(),
            ) {
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .wrapContentHeight()
                        .semantics(mergeDescendants = true) {
                            isTraversalGroup = true
                        },
                ) {
                    Text(
                        modifier = Modifier.semantics {
                            traversalIndex = 1f
                        },
                        text = "Show my name.",
                    )
                    Switch(
                        modifier = Modifier.semantics {
                            traversalIndex = 2f
                        },
                        checked = toggle,
                        onCheckedChange = { toggle = !toggle },
                    )
                }
            }

For some reason only the Text gets read out and the default line of switch is ignored. My goal is to have it read like "Show my name. On/Off switch double tap to toggle". In one go. How can I achieve this?

1

There are 1 best solutions below

0
Quintin Balsdon On BEST ANSWER

According to the documentation:

When implementing selection controls like Switch, RadioButton, or Checkbox, you typically lift the clickable behavior to a parent container, set the click callback on the composable to null, and add a toggleable or selectable modifier to the parent composable.

So using the toggleable modifier on the row in your case would look something like:

    var toggle by remember {
        mutableStateOf(true)
    }
    Column(
        modifier = Modifier.fillMaxSize(),
    ) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentHeight()
                .toggleable(
                    value = toggle,
                    role = Role.Switch,
                    onValueChange = { toggle = !toggle }
                )
        ) {
            Text(
                text = "Show my name.",
                modifier = Modifier
                    .weight(1f)
                    .align(Alignment.CenterVertically)
            )
            Switch(
                checked = toggle,
                onCheckedChange = null,
            )
        }
    }

I tried it with basic keyboard functions as well and it seems to work:

adb shell input keyevent KEYCODE_TAB    # navigate
adb shell input keyevent KEYCODE_ENTER  # toggle

If the order of the announcement concerns you ('On, [Text], Switch'), please be aware that this can be modified by user settings of TalkBack and is a result of the calculations on the screen reader (TalkBack).

A test android app with three elements in a column, a text view with 'element 1', the element in question, a text view with a switch, and a third text view with 'element 3.' The screen read goes to the switch row which reads 'On, Show My Name, Switch.' and when toggled, it goes 'Off'