android 在Jetpack Compose中更改光标位置并强制TextField为单行

jvidinwx  于 2023-08-01  发布在  Android
关注(0)|答案(2)|浏览(339)

无法找到更改文本字段的光标位置并使其成为单行的方法。有人找到办法了吗?
目前,我使用的是最新的jetpack-compose 1.0.0-alpha03版本。

9rnv2umw

9rnv2umw1#

要设置光标,您需要像这样设置TextFieldValue的选择:

@Composable
fun Content() {
    val initTargetIndex = 3
    val initValue = "string"
    val initSelectionIndex = initTargetIndex.takeIf { it <= initValue.length } ?: initValue.length
    val textFieldValueState = remember {
        mutableStateOf(TextFieldValue(
            text = initValue,
            selection = TextRange(initSelectionIndex)
        ))
    }
    TextField(
        modifier = Modifier.height(50.dp),
        value = textFieldValueState.value,
        onValueChange = { tfv -> textFieldValueState.value = tfv}
    )
}

字符串
请记住,您需要自己从onValueChange更新选择,否则用户无法移动光标或键入/delete。
对于单行,您需要在TextField Composable上设置一个固定的高度,并且您可能希望从用户输入中清理'\n'。

@Composable
fun Content() {
    val initTargetIndex = 3
    val initValue = "string"
    val initSelectionIndex = initTargetIndex.takeIf { it <= initValue.length } ?: initValue.length
    val textFieldValueState = remember {
        mutableStateOf(TextFieldValue(
            text = initValue,
            selection = TextRange(initSelectionIndex)
        ))
    }
    TextField(
        modifier = Modifier.height(50.dp),
        value = textFieldValueState.value,
        onValueChange = { tfv ->
            val sanitizedText = tfv.text.replace("\n", "")
            val needUpdate = sanitizedText.length >= tfv.text.length
            if (needUpdate) {
                textFieldValueState.value = tfv
            }
        },
    
    )
}


对于后者,我清理新文本并比较它和状态文本的长度,如果新文本更短,我不必更新状态,因为我只是在清理过程中删除了字符。如果您只是想阻止用户自己添加新行,则可以不限制高度。
前面的解决方案忽略了一个带有换行符的粘贴文本,如果你想保留它,这个onValueChange实现应该正确处理它:

val onValueChange = {tfv ->
    textFieldValueState.value.let { old ->
        val sanitizedText = tfv.text.replace("\n", "")
        val lastPositionIndex = sanitizedText.length
        val needUpdate = sanitizedText.length < tfv.text.length
        val selection = if (needUpdate) {
            tfv.selection.copy(
                start = old.selection.start.takeUnless { it > lastPositionIndex} ?: lastPositionIndex,
                end = old.selection.end.takeUnless { it > lastPositionIndex} ?: lastPositionIndex
            )
        } else tfv.selection
        val composition = old.composition?.let { oldComp ->
            if (needUpdate) {
               TextRange(
                    start = oldComp.start.takeUnless { it > lastPositionIndex} ?: lastPositionIndex,
                    end = oldComp.end.takeUnless { it > lastPositionIndex} ?: lastPositionIndex
                )
            } else oldComp
        }
        textFieldValueState.value = tfv.copy(text = sanitizedText, selection = selection, composition = composition)
    }
}

qacovj5a

qacovj5a2#

@Composable
fun MyScreen() {
    var textState by remember { mutableStateOf("Hello, world!") }
    val focusRequester = remember { FocusRequester() }
    Column(
        modifier = Modifier.padding(16.dp),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        BasicTextField(
            value = TextFieldValue(textState, selection = TextRange(textState.length)),
            onValueChange = { textState = it.text },
            modifier = Modifier
                .fillMaxWidth()
                .focusRequester(focusRequester),
        )
        Button(
            onClick = {
                // Request focus and set the cursor at the end of the text when the button is clicked
                focusRequester.requestFocus()
            },
            modifier = Modifier.padding(top = 16.dp)
        ) {
            Text("Move Cursor to End")
        }
    }
}

字符串
val focusRequester = remember { FocusRequester() }:此行使用remember函数声明了一个FocusRequester对象。FocusRequester用于通过编程方式请求关注BasicTextField
点击按钮后,调用focusRequester.requestFocus(),通过编程方式请求对BasicTextField进行聚焦。


的数据

相关问题