I am making custom components and with my custom components I am required to cover the focus state.
At the top of my component hierarchy I am tracking focus with this.
val focused = remember { mutableStateOf(false) }
val focusModifier = modifier.onFocusEvent {
focused.value = it.hasFocus || it.isFocused
}
Component(modifier = focusModifier, focused = focused.value)
The component is basically this:
@Composable
fun Component(
modifier: Modifier = Modifier,
focused: Boolean = false
) {
...
val colorStuff = if(focused) focusColors else otherColors
var focusModifier = modifier
if(focused) {
focusModifier = modifier.border(BorderStroke(2.dp, Color.Red)).padding(16.dp)
}
NextComponent(
focusModifier,
colorStuff,
etc
)
}
If I leave the code with colorStuff and focused without the focusModifier code the focus state is done correctly and the colors for the component change appropriately. But when I add the focusModifier code and do a border and padding the focus state will trigger, but then instantly be lost. I'm assuming this is because the addition of modifier code changes the build order of the component and makes it discard focus. But that doesn't make full sense either.
I essentially need to add borders/shadows around components when they are focused so this will be something I have to do multiple times. Right now I can't get it done once. Any idea what I need to do to overcome this?
@Composable
fun FocusableButton(
modifier: Modifier = Modifier,
onClick: () -> Unit = {},
label: String,
enabled: Boolean = true,
requestInitialFocus: Boolean = false
) {
var backgroundColor by remember { mutableStateOf(FocusButtonUnselectedBackground) }
var borderColor by remember { mutableStateOf(FocusButtonSelectedBorder) }
fun applyColors(focusState: FocusState) {
borderColor = if (focusState.isFocused) {
FocusButtonSelectedBorder
} else {
FocusButtonUnselectedBorder
}
backgroundColor = if (focusState.isFocused) {
FocusButtonSelectedBackground
} else {
FocusButtonUnselectedBackground
}
}
val newModifier = if (requestInitialFocus) {
val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) {
focusRequester.requestFocus()
}
modifier
.onFocusEvent(::applyColors)
.focusRequester(focusRequester)
.focusable()
} else {
modifier
.onFocusEvent(::applyColors)
.focusable()
}
OutlinedButton(
onClick = { onClick() },
modifier = newModifier,
enabled = enabled,
border = BorderStroke(1.dp, borderColor),
colors = ButtonDefaults.buttonColors(backgroundColor = backgroundColor)
) {
Text(text = label)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With