Home > database >  How to keep focus on an element after recompose?
How to keep focus on an element after recompose?

Time:04-14

I have a custom component in my Compose Desktop app, which can have the focus:

val focusRequester = remember { FocusRequester() }
var focused by remember { mutableStateOf(false) }
Row(modifier.fillMaxWidth()
    .focusRequester(focusRequester)
    .onFocusChanged { state -> focused = state.isFocused }

This works as you'd expect. However, when I add a border based on focused state, it breaks:

val focusRequester = remember { FocusRequester() }
var focused by remember { mutableStateOf(false) }
Row(Modifier.fillMaxWidth()
    .focusRequester(focusRequester)
    .onFocusChanged { state -> focused = state.isFocused }
    .border(if (focused) 1.dp else 0.dp, MaterialTheme.colors.primary)

From what I can tell, the recompose actually causes the onFocusedChanged to fire again with isFocused = false. So that's the problem, not the remembering of the focused property itself.

How can my component keep the focus after recomposing to draw the border?

CodePudding user response:

You can use interactionSource.collectIsFocusedAsState() instead of the onFocusChanged modifier.

Something like:

val focusRequester = remember { FocusRequester() }
val interactionSource = remember { MutableInteractionSource() }
val focused by interactionSource.collectIsFocusedAsState()

    Row(Modifier
         // add focusRequester modifier before the focusable (or even in the parent)
        .focusRequester(focusRequester)
        .focusable(interactionSource = interactionSource)
        .border(if (focused) 1.dp else 0.dp, MaterialTheme.colors.primary)
  • Related