在 Jetpack 中请求焦点在 TextField 中撰写

Request Focus in Jetpack compose in TextField

这就是我的可组合项的样子

@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")
    }
  }
}

我已经添加了解释的基本代码,我在单击按钮时遇到 focusRequester 问题。

出于可访问性的原因,单击按钮后,如果电子邮件无效,我希望焦点返回到 TextField,以便可访问性可以宣布其状态和标签。

我尝试清除焦点然后再次请求它,但它只适用于第一次。我希望 TextField 在每次单击按钮且电子邮件无效时获得焦点。

我是不是遗漏了什么?

  1. 试试这个,它工作得很好。

@Composable
fun Test() {
    val context = LocalContext.current
    val emailState = remember { mutableStateOf("") }
    val focusRequester = remember { FocusRequester() }
    val focusManager = LocalFocusManager.current

    Column {
        TextField(
            modifier = Modifier
                .focusRequester(focusRequester)
                .fillMaxWidth(),
            value = emailState.value,
            onValueChange = {
                emailState.value = it
            },
        )
        Button(onClick = {
            focusManager.clearFocus()
            if (emailState.value.isEmpty() ) {
                focusRequester.requestFocus()
                Toast.makeText(context, "error", Toast.LENGTH_SHORT).show()
            }
        }) { Text(text = "Button")
        }
    }
}

如果单击 button 后,如果 TextField 已经获得焦点,我找不到任何方法让焦点重新回到 TextField 上。

我最终使用 live-region 进行公告。

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")
    }
  }