androidandroid-jetpack-composeandroid-tvandroid-compose-buttonandroid-jetpack-compose-tv

How to set a focused state to a Button with jetpack compose?


compose_version = '1.0.0-beta02'.

I can set a focused state TextField by FocusRequester, but Button not.

        val requester1 = FocusRequester()
       
        TextField(value = text1,
            { newValue ->
                text1 = newValue
            },
            modifier = Modifier
                .focusable(true)
                .focusRequester(requester1)
                .background(focusedColor1)
                .onFocusChanged {
                    focusedColor1 = if (it.isFocused) {
                        text1 = "TextField1 focused"
                        Color.Red
                    } else {
                        text1 = "TextField1 unfocused"
                        Color.Green
                    }
                }

        )

The method "onFocusChanged" of TextField would be invoked.

        val requester3 = FocusRequester()
        Button(
            onClick = {
                requester3.requestFocus()

            },
            modifier = Modifier
                .focusModifier()
                .focusable(true)
                .focusRequester(requester3)
                .onFocusEvent {
                    Toast
                        .makeText(
                            context,
                            "Button onFocusEvent it.isFocused:${it.isFocused}. ${it.name}",
                            Toast.LENGTH_SHORT
                        )
                        .show()
                }
                .onFocusChanged {
                    Toast
                        .makeText(
                            context,
                            "Button onFocusChanged it.isFocused:${it.isFocused}",
                            Toast.LENGTH_SHORT
                        )
                        .show()
                }.background(Color.Red)

        ) {
            Text(text = text2,Modifier.background(Color.Red))
        }

But the method "onFocusChanged" of Button would not be invoked.


Solution

  • Use something like:

    val focusRequester = FocusRequester()
    val interactionSource = remember { MutableInteractionSource() }
    val isFocused = interactionSource.collectIsFocusedAsState().value
    // if (isFocused....)
    
    Button(
        onClick = {
            focusRequester.requestFocus()
        },
        modifier = Modifier
            // add focusRequester modifier before the focusable (or even in the parent)
            .focusRequester(focusRequester)
            .focusable(interactionSource = interactionSource)
     ){ ...  }