By pressing one of 2 buttons, I can add a text "Apple" or "Orange" at the start of a list, in which that list will be displayed in a column on top. Each new text will appear at the top of the list.
val myList = remember { mutableStateListOf<String>() }
val focus = remember { FocusRequester() }
Column {
myList.forEachIndexed { index, word ->
Text(
text = word,
modifier =
if (index == 0) {
Modifier
.focusRequester(focus)
.focusable()
} else {
Modifier
}
)
}
if (myList.isNotEmpty()) {
focus.requestFocus()
}
Button(
onClick = {
myList.add("Apple")
},
modifier = Modifier.padding(top = 8.dp)
) {
Text("Add Apple")
}
Button(
onClick = {
myList.add("Orange")
},
modifier = Modifier.padding(top = 8.dp)
) {
Text("Add Orange")
}
}
This doesn't work for some reason.
Out of curiosity, I checked to see what would happen if I changed it so that the last item would be focused:
if (index == myList.size -1) {
Modifier
.focusRequester(focus)
.focusable()
} else {
Modifier
}
When trying that, the accessibility focus goes to the last text, at the bottom of the list.
So why is it that I the focus only works if it's the last item of the list, but not the first (or any item before)?
Is there a way to fix it?
To trigger talkback you should refocus a composable by clearing focus first with FocusManager.clearFocus()
. It can be done by launching a coroutine in buttons' onClick
handlers.
val myList = remember { mutableStateListOf<String>() }
val focusRequester = remember { FocusRequester() }
val focusManager = LocalFocusManager.current
val scope = rememberCoroutineScope()
Column {
myList.forEachIndexed { index, word ->
var color by remember { mutableStateOf(Black) }
Text(
text = word,
modifier =
if (index == 0) {
Modifier
.focusRequester(focusRequester)
.focusable()
} else {
Modifier
}
)
}
fun refocus() = scope.launch {
delay(50)
focusManager.clearFocus()
delay(50)
focusRequester.requestFocus()
}
Button(
onClick = {
myList.add(0, "Apple")
refocus()
},
modifier = Modifier.padding(top = 8.dp)
) {
Text("Add Apple")
}
Button(
onClick = {
myList.add(0, "Orange")
refocus()
},
modifier = Modifier.padding(top = 8.dp)
) {
Text("Add Orange")
}
}
There should be a small delay
before requestFocus()
in LaunchedEffect
just to be sure that it executes after focusRequester
modifier.