any*_*iek 3 textfield kotlin android-jetpack-compose
我在 Jetpack Compose 中使用 TextField 组件。获得焦点时如何选择所有文本?
@nglauber 解决方案似乎不再起作用了。
调试显示该函数在一个视图生命周期onFocusChanged之前和之内被调用。onValueChange在 期间更改的选择onFocusChanged对 没有影响TextField,因为它在 期间被覆盖onValueChange。
这是一个可能的解决方法:
var state by remember {
mutableStateOf(TextFieldValue("1231"))
}
var keepWholeSelection by remember { mutableStateOf(false) }
if (keepWholeSelection) {
// in case onValueChange was not called immediately after onFocusChanged
// the selection will be transferred correctly, so we don't need to redefine it anymore
SideEffect {
keepWholeSelection = false
}
}
TextField(
value = state,
onValueChange = { newState ->
if (keepWholeSelection) {
keepWholeSelection = false
state = newState.copy(
selection = TextRange(0, newState.text.length)
)
} else {
state = newState
}
},
modifier = Modifier
.onFocusChanged { focusState ->
if (focusState.isFocused) {
val text = state.text
state = state.copy(
selection = TextRange(0, text.length)
)
keepWholeSelection = true
}
}
)
Run Code Online (Sandbox Code Playgroud)
我认为应该可以让它变得更容易,所以我在 Compose 问题跟踪器上创建了这个问题。
我编写了一个修饰符扩展函数,尽管存在 @Pylyp 指出的错误,它仍然可以工作
fun Modifier.onFocusSelectAll(textFieldValueState: MutableState<TextFieldValue>): Modifier =
composed(
inspectorInfo = debugInspectorInfo {
name = "textFieldValueState"
properties["textFieldValueState"] = textFieldValueState
}
) {
var triggerEffect by remember {
mutableStateOf<Boolean?>(null)
}
if (triggerEffect != null) {
LaunchedEffect(triggerEffect) {
val tfv = textFieldValueState.value
textFieldValueState.value = tfv.copy(selection = TextRange(0, tfv.text.length))
}
}
onFocusChanged { focusState ->
if (focusState.isFocused) {
triggerEffect = triggerEffect?.let { bool ->
!bool
} ?: true
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法
@Composable
fun SelectAllOnFocusDemo() {
var tfvState = remember {
mutableStateOf(TextFieldValue("initial text"))
}
TextField(
modifier = Modifier.onFocusSelectAll(tfvState),
value = tfvState.value,
onValueChange = { tfvState.value = it },
)
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您应该使用TextFieldValueas 的状态TextField,当它获得焦点时,设置selectionusingTextFieldValue状态。
val state = remember {
mutableStateOf(TextFieldValue(""))
}
TextField(
value = state.value,
onValueChange = { text -> state.value = text },
modifier = Modifier
.onFocusChanged { focusState ->
if (focusState.isFocused) {
val text = state.value.text
state.value = state.value.copy(
selection = TextRange(0, text.length)
)
}
}
)
Run Code Online (Sandbox Code Playgroud)
结果如下:
请注意,根据您触摸的情况,光标会转到触摸的位置,而不是选择整个文本。您可以尝试弄清楚这是错误还是功能:)