Search code examples
android-jetpack-composeaccessibility

Jetpack Compose keyboard focus vs clickable indication highlight


For a while I thought item focus is the same thing as focus highlight. But I am confused. I have this example below:

var color by remember { mutableStateOf(Green) }

Box(
    modifier = Modifier
        .background(color)
        .focusable()
        .onFocusChanged { color =
            if (it.isFocused)
                Blue
            else
                Green
        }
) {
    Text(
        text = "Some content",
        style = MaterialTheme.typography.h1
    )
}

When I move the keyboard focus to this item, nothing happens. Even though I would have expected that the keyboard focus would actually - you know - focus on the item and the item's background would turn blue. But it does not.

If I add

.clickable {  }

on to this item, I can see that the keyboard focus is on this item by a grey'ish overlay. This is because it now uses the default Indication on this item. But also in this case, the color does not change.

So how do I focus on items in Compose? And how does keyboard focus relate to this?


Solution

  • You need to switch the order of the focusable and the onFocusChanged modifier since the order of modifiers is important. As stated in this issue https://issuetracker.google.com/issues/186567354,

    The focus modifier holds the focus state. When focus state changes, it calls all focus modifers preceeding it.

    So this should work:

    var color by remember { mutableStateOf(Green) }
    
    Box(
        modifier = Modifier
            .background(color)
            .onFocusChanged { color =
                if (it.isFocused)
                    Blue
                else
                    Green
            }
            .focusable()
    ) {
        Text(
            text = "Some content",
            style = MaterialTheme.typography.h1
        )
    }