【问题标题】:Enable and focus Textfield at once in Jetpack Compose在 Jetpack Compose 中立即启用和聚焦 Textfield
【发布时间】:2022-12-15 04:41:42
【问题描述】:

我正在尝试在 Jetpack Compose 中使用以下功能实现 TextField:起初它被禁用,但是当用户按下 Button 时,它被启用并同时获得焦点。这是我的方法:

var text by remember { mutableStateOf("text") }
var enabled by remember { mutableStateOf(false)}
val focusRequester = remember { FocusRequester() }

Column {
    TextField(
        value = text,
        onValueChange = { text = it },
        enabled = enabled,
        modifier = Modifier.focusRequester(focusRequester),
        textStyle = TextStyle(fontSize = 24.sp)
    )
    Button(onClick = {
        enabled = true
        focusRequester.requestFocus()
    }) {
        Text("Enable and request focus")
    }

但是当按下按钮时,TextField 只会被启用,不会被聚焦。要聚焦它,用户必须再次单击它。我做错了什么,可能的解决方法是什么?

【问题讨论】:

    标签: android android-jetpack-compose android-jetpack-compose-text


    【解决方案1】:

    您必须监听enabled 参数的变化,才能将焦点转移到TextField

    您可以将代码更改为:

        Button(onClick = {
            enabled = true
    
        }) {
            Text("Enable and request focus")
        }
    
        LaunchedEffect(enabled) {
            if (enabled){
                focusRequester.requestFocus()
            }
        }
    

    【讨论】:

    • 谢谢!那是我一直在寻找的解决方案。
    • 仍然存在一个问题,即即使 TextField 已获得焦点,键盘仍处于隐藏状态。
    • @IvanAbramov 我已经用1.0.51.1.0-rc01 尝试了代码,键盘出现了。我无法重现您的问题。尝试添加:val keyboardController = LocalSoftwareKeyboardController.current并在requestFocus()之后调用keyboardController.show()
    • 谢谢,当我更新到1.1.0-rc1时有用
    【解决方案2】:

    像这样启用文本字段后只需添加延迟:

    var text by remember { mutableStateOf("text") }
    var enabled by remember { mutableStateOf(false)}
    val focusRequester = remember { FocusRequester() }
    val scope = rememberCoroutineScope()
    
    Column {
        TextField(
            value = text,
            onValueChange = { text = it },
            enabled = enabled,
            modifier = Modifier.focusRequester(focusRequester),
            textStyle = TextStyle(fontSize = 24.sp)
        )
        Button(onClick = {
            scope.launch {
                enabled = true
                delay(100)
                focusRequester.requestFocus()
            }
        }) {
            Text("Enable and request focus")
        }
    }
    

    【讨论】:

    • 谢谢,这行得通。我只是想知道我怎么知道这 100 毫秒总是足够的?
    • 如果您不确定 100 毫秒的延迟是否足够,我相信最好的方法是使用 Gabriele 回答的 DisposableEffect。
    • 为什么我们要延迟?
    【解决方案3】:

    我曾经有过类似的问题,我使用interactionSource 解决了它。代码看起来像这样:

    var text by remember { mutableStateOf("text") }
    var enabled by remember { mutableStateOf(false)}
    val focusRequester = remember { FocusRequester() }
    val interactionSource = remember { MutableInteractionSource() } // add this
    
    Column {
        TextField(
            value = text,
            onValueChange = { text = it },
            enabled = enabled,
            modifier = Modifier
                .focusable(interactionSource = interactionSource) // and this
                .focusRequester(focusRequester),
            textStyle = TextStyle(fontSize = 24.sp)
        )
        ...
    

    IIRC 以正确的顺序使用 .focusable().focusRequester() 很重要,但不记得具体是哪一个,所以如果它不能立即工作,请尝试交换它们。

    【讨论】:

    • 不幸的是,这些都不起作用:(
    猜你喜欢
    • 2022-06-15
    • 2023-01-16
    • 2021-11-14
    • 1970-01-01
    • 2023-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    相关资源
    最近更新 更多