Search code examples
androidandroid-jetpack-composeandroid-jetpack

Request Focus in Jetpack compose in TextField


This his how my composable looks like

@Composable
fun MyComposable(
 email:String?,
 onEmailChanged:(email)-> Unit,
 buttonClicked:()->Unit,
 validEmail:Boolean
){
    val focusRequester = remember { FocusRequester() }
    val focusManager = LocalFocusManager.current
    val keyboardController = LocalSoftwareKeyboardController.current

    TextField(
      modifier = Modifier
        .fillMaxWidth()
        .focusRequester(focusRequester = focusRequester),
      value = email ?: "",
      status = someStatus // Default, Error, Success
      onValueChange = { email -> onEmailChanged(email)},
    )
    Button(
      onClick = {
        focusManager.clearFocus()
        buttonClicked()
        if(!validEmail) focusRequester.requestFocus()
      },
    ) {
      Text(text = "Button")
    }
  }
}

I have added the basic code for explanation, i am facing issue with focusRequester when a button is clicked.

For accessibility reasons once the button is clicked, and if the email is invalid, i would like the focus to go back to TextField so that accessibility can announce it's state and label.

I tried clearing the focus and then requesting it again, but it only works for the first time. And i would like the TextField to gain focus every-time a button is clicked and email is invalid.

Am i missing something here?


Solution

  • I couldn't find any way to get the focus back on TextField if it was already focused, once the button was clicked.

    I ended up using live-region for announcement.

    TextField(
          modifier = Modifier
            .fillMaxWidth()
            .semantics {
              liveRegion = LiveRegionMode.Assertive
            }),
          value = email ?: "",
          status = someStatus // Default, Error, Success
          onValueChange = { email -> onEmailChanged(email)},
        )
        Button(
          onClick = {
            focusManager.clearFocus()
            buttonClicked()
          },
        ) {
          Text(text = "Button")
        }
      }