I have a custom composable View (Surface + Text essentially) and I want to change the color of the surface depending on the focus state. The FocusManager#FocusNode is marked internal and I am unaware of any way to achieve this. Is this simply just not available yet? Any one else have to tackle this?
How to manage Focus state in Jetpack's Compose
22.5k Views Asked by Maurycy At
4
There are 4 best solutions below
2
On
With 1.0.x you can use the Modifier.onFocusChanged to observe focus state events.
Something like:
var color by remember { mutableStateOf(Black) }
val focusRequester = FocusRequester()
Text(
modifier = Modifier
.focusRequester(focusRequester)
.onFocusChanged { color = if (it.isFocused) Green else Black }
.focusModifier()
.pointerInput(Unit) { detectTapGestures { focusRequester.requestFocus() } },
text = "Text",
color = color
)
0
On
this code works for me
var haveFocus by remember { mutableStateOf(false) }
Surface(
modifier = Modifier.onFocusEvent {
haveFocus = it.isFocused
},
shape = RectangleShape
){...}
0
On
This answer is base on Gabriele Mariotti answer but I have change
- Use
remember { FocusRequester() }to prevent crashFocusRequester is not initializedafter do 2nd click onText - Use
focusTargetinstead offocusModifierbecause deprecated
.
var color by remember { mutableStateOf(Color.Black) }
val focusRequester = remember { FocusRequester() }
Text(
text = "Hello",
modifier = Modifier
.focusRequester(focusRequester)
.onFocusChanged { color = if (it.isFocused) Color.Green else Color.Black }
.focusTarget()
.pointerInput(Unit) { detectTapGestures { focusRequester.requestFocus() } }
)
As of
dev11,FocusManagerAmbienthas been deprecated in favor ofFocusModifier. For more examples check out the KeyInputDemo, ComposeInputFieldFocusTransition or FocusableDemo.Compose has since updated and made the
FocusManagermemberspublic; although, I'm not exactly sure how final the api is as ofdev10. But as of now you can create aFocusNodeand listen for changes usingFocusManager.registerObserver.If you'd like to gain focus, you can now call
FocusManager.requestFocus:You can also set a
focusIdentifieron yourFocusNode:To gain focus for a specific identifier, you just call
FocusManager.requestFocusByIdUsing that you can easily create a
Composablethat can provide and request focus for you, for instance:You could also compose children along with it:
Alternatively, there's also
FocusModifier, which as of now is:But I don't think you can apply an identifier with it right now.
All that being said, I'm not 100% sure this is the intended way to handle focus right now. I referenced CoreTextField a lot to see how it was being handled there.
Example: