Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Compose component non-focusable?

I have a Composable Row that has some click listeners:

val action = { ... }
Row(Modifier.clickable(action) {
  IconButton({ /* other, unrelated action */}) {}
  Text("This isn't clickable")
  Checkbox({ /* something that calls action() on toggle */ })
}

When tabbing through this UI, the focus goes to the IconButton, then the Checkbox, then the Row. I want it to skip the row. I've implemented that by adding to the Row modifier:

val manager = LocalFocusManager.current
Row(Modifier.clickable(action).onFocusChanged { 
  if (it.isFocused) manager.moveFocus(FocusDirection.Next) 
}) { /* same content */ }

... which works when moving forward, but not when moving backward (using Shift-Tab). And of course that's because of the FocusDirection.Next, which should instead be Previous when moving backward. But how do I detect that? The focus event doesn't have a direction property.

Update
I tried doing this by manually detecting if shift is pressed, which feels more like a hack than a solution:

val keys = LocalWindowInfo.current.keyboardModifiers
/* in onFocusChanged */
manager.moveFocus(if (keys.isShiftPressed) FocusDirection.Previous else FocusDirection.Next)

.. and also, it doesn't work. Calling manager.moveFocus(FocusDirection.Previous) if shift is pressed causes an infinite loop and application crash, presumably because it's setting the focus back to where it came from.


1 Answers

Modifier.focusProperties { canFocus = false } should help you!

An example of usage:

Row(Modifier.focusProperties { canFocus = false }.clickable(onClick = action)) {
  IconButton({ action() }) {
    Text("IconButton")
  }
  Text("This isn't clickable")
  Button(onClick = { action() }) {
    Text("Button")
  }
}
like image 180
Nikolai Rykunov Avatar answered Nov 04 '25 02:11

Nikolai Rykunov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!