android 在jetpack合成中请求聚焦于TextField

h5qlskok  于 2023-01-15  发布在  Android
关注(0)|答案(8)|浏览(197)

如何在jetpack编写中自动聚焦文本字段。当我点击文本字段并开始输入时。同时当我点击后退按钮,然后当我试图点击文本字段时,什么都没有发生。

val textState = remember { mutableStateOf(TextFieldValue()) }
TextField(
    modifier = Modifier.fillMaxWidth(),
    value = textState.value,
    onValueChange = { value : TextFieldValue ->
        textState.value = value
    }
)
oug3syen

oug3syen1#

发布问题的更新答案(API在编写测试版中重命名)

@Composable
fun AutoFocusingText() {
    var value by mutableStateOf("Enter Text")
    val focusRequester = remember { FocusRequester() }
    TextField(
        value = value, 
        onValueChange = { value = it },
        modifier = Modifier.focusRequester(focusRequester)
    )
    
    LaunchedEffect(Unit) {
        focusRequester.requestFocus()
    }
}
1dkrff03

1dkrff032#

您可以使用带有SideEffect的FocusRequester
比如:

var text by remember { mutableStateOf("text") }

// initialize focus reference to be able to request focus programmatically
val focusRequester = FocusRequester()

Column {
    TextField(
        value = text,
        onValueChange = {
            text = it
        },
        label = { Text("label") },
        modifier = Modifier
            // add focusRequester modifier 
            .focusRequester(focusRequester)
    )

然后使用**focusRequester.requestFocus()**。这样,系统将焦点授予与此FocusRequester关联的组件。
要在屏幕出现时自动聚焦字段,可以使用:

LaunchedEffect(Unit) {
    focusRequester.requestFocus()
}

要手动将焦点授予字段:

Button(
         onClick = { focusRequester.requestFocus() }
    ){
        Text("Click to give the focus")
    }
stszievb

stszievb3#

val focusRequester = remember { FocusRequester() }
val inputService = LocalTextInputService.current
val focus = remember { mutableStateOf(false) }
BasicTextField(
    value = "value",
    modifier = Modifier
        .height(40.dp)
        .fillMaxWidth()
        .focusRequester(focusRequester)
        .onFocusChanged {
            if (focus.value != it.isFocused) {
                focus.value = it.isFocused
                if (!it.isFocused) {
                    inputService?.hideSoftwareKeyboard()
                }
            }
        },
),

LaunchedEffect("") {
    delay(300)
    inputService?.showSoftwareKeyboard()
    focusRequester.requestFocus()
}
l2osamch

l2osamch4#

取自合成单元测试并应用于TextField Link

@ExperimentalFocus
    @Composable
    fun AutoFocusingText() {
        val textState = remember { mutableStateOf(TextFieldValue()) }
        val focusState = remember { mutableStateOf(FocusState.Inactive) }
        val focusRequester = FocusRequester()
        val focusModifier = Modifier.focus()
        Row(
            modifier = Modifier.focusObserver { focusState.value = it }
        ) {
            val focusRequesterModifier = Modifier.focusRequester(focusRequester)
            TextField(
                modifier = focusModifier.then(focusRequesterModifier),
                value = textState.value,
                onValueChange = { value: TextFieldValue ->
                    textState.value = value
                },

                )
        }
        onActive {
            focusRequester.requestFocus()
        }
    }

编辑:将框更改为行,因为框在“1.0.0-alpha 04”中已弃用

bqucvtff

bqucvtff5#

如果你想让你的文本字段在你导航到屏幕时自动聚焦,你可以使用这个。这允许你在合成过程中不要requestFocus,这不是你应该做的。否则,你会得到IllegalStateException,有时会显示消息“FocusRequester is not initialized”。

@Composable fun YourComposable(){ 
   val focusRequester = remember {FocusRequester()}
    
        LaunchedEffect(Unit) {
            this.coroutineContext.job.invokeOnCompletion {
                focusRequester.requestFocus()
            }
        }
    
       OutlinedTextField( modifier = Modifier.focusRequester(focusRequester))
         
              
}

这是因为LaunchedEffect离开合成时,LaucnhedEffeect内部的协程将被取消。

wribegjk

wribegjk6#

@Composable fun SomeComposable() {
        val focusRequester = remember { FocusRequester() }

    OutlinedTextField(
        value = TextFieldValue(
        text = state.text, // state come from else where
        selection = TextRange(state.text.length,state.text.length)),  
   
        onValueChange = { _:TextFieldValue -> Unit },
        modifier = Modifier
          .fillMaxWidth()
          .focusRequester(focusRequester),)

    SideEffect {
        focusRequester.requestFocus()
        }
    }

为什么选择SideEffect:文档的第一行。
对于光标位置this answer helped。onValueChanged在我的工作代码中保持原样,我不需要它。

xjreopfe

xjreopfe7#

将光标移动到文本的长度,并允许用户使用以下代码将光标移动到TextField

@Composable
    fun AutoFocusingText(value:String,onValueChange: (newValue: String) -> Unit) {
    var textFieldValueState by remember { mutableStateOf(TextFieldValue(text = value,selection = TextRange(value.length))) }
    val textFieldValue = textFieldValueState.copy(text = value)
    val focusRequester = FocusRequester()
    DisposableEffect(Unit) {
        focusRequester.requestFocus()
        onDispose { }
    }
    TextField(
        value = textFieldValue,
        onValueChange = {
            textFieldValueState = it
            if (value != it.text) {
                onValueChange(it.text)
            } },
        modifier = Modifier.focusRequester(focusRequester = focusRequester)
    )

}
jk9hmnmh

jk9hmnmh8#

在最新版本的Jetpack Compose(目前为1.3.3)中,如果您使用以下命令:

LaunchedEffect(Unit) {
    focusRequester.requestFocus()
}

尝试自动对焦TextField,您将获得:

java.lang.IllegalStateException:
FocusRequester is not initialized. Here are some possible fixes:

    1. Remember the FocusRequester: val focusRequester = remember { FocusRequester() }
    2. Did you forget to add a Modifier.focusRequester() ?
    3. Are you attempting to request focus during composition? Focus requests should be made in
    response to some event. Eg Modifier.clickable { focusRequester.requestFocus() }

下面是一个不使用delay的优雅解决方案:

val focusRequester = remember { FocusRequester() }

TextField(
    modifier = Modifier
        .focusRequester(focusRequester)
        .onGloballyPositioned {
            focusRequester.requestFocus() // IMPORTANT
        },
    value = someValue,
    onValueChange = {
        // ...
    }
)

// We don't need this
// LaunchedEffect(Unit) {
//     focusRequester.requestFocus()
// }

相关问题