Reputation: 3733
With Android View, I'm able to move the focus to a View like so:
fun View.requestAccessibilityFocus() {
requestFocus()
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED)
}
How do I achieve this in Jetpack Compose?
I tried using FocusRequester but it doesn't seem to do anything:
val lifecycleOwner = LocalLifecycleOwner.current
val requester = FocusRequester()
Box {
...
Image(
...
contentDescription = "My heading",
modifier = Modifier
...
.focusRequester(requester)
)
}
DisposableEffect(lifecycleOwner) {
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_RESUME) {
requester.requestFocus()
}
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose { lifecycleOwner.lifecycle.removeObserver(observer) }
}
Upvotes: 9
Views: 5912
Reputation: 3733
I had to add .focusable()
and must do so after .focusRequester(focusRequester)
.
Box {
...
Image(
...
contentDescription = "My heading",
modifier = Modifier
...
.focusRequester(requester)
.focusable()
)
}
Upvotes: 6
Reputation: 973
This happens because DiposableEffect
might be calling during recomposition. You should not request focus during composition. The solution I have found is to request a focus right after the composition. Like this
LaunchedEffect(Unit) {
this.coroutineContext.job.invokeOnCompletion {
focusRequester.requestFocus()
}
}
This makes sure your code will run when the LauchedEffect leaves the composition because it(the coroutine) either got canceled or completed.
Upvotes: 3