Reputation: 2905
I have list of text suggestions chip view above textfield, when user clicking chip I am appending the text into textfield. after that I want to move the cursor to the end position. I couldn't find solution for this in Jetpack compose. earlier we used editText.setSelection(position)
to change cursor position in android views.
How to set a cursor position in jetpack compose Textfield?
OutlinedTextField(
value = value,
onValueChange = { value = it },
maxLines = 8,
label = {
Text(
text = "Content",
maxLines = 1
)
},
modifier = Modifier
.fillMaxWidth()
.height(200.dp),
shape = RoundedCornerShape(2.dp),
)
Upvotes: 41
Views: 38166
Reputation: 679
@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() }
:
This line declares a FocusRequester object using the remember function. The FocusRequester is used to request focus on the BasicTextField programmatically.
when the button is clicked, it calls focusRequester.requestFocus() to request focus on the BasicTextField programmatically.
Upvotes: 3
Reputation: 10212
a "selection" should be used and TextFieldValue:
@Composable
fun CustomTextField() {
val textState = remember { mutableStateOf(TextFieldValue(viewState.contextText)) }}
val focusRequester = remember { FocusRequester() }
BasicTextField(
value = textState.value,
onValueChange = {
textState.value = it
viewModel.onContextText(it.text)
}
modifier = Modifier.focusRequester(focusRequester),
textStyle = ...
)
LaunchedEffect(Unit) {
focusRequester.requestFocus()
}
// Set cursor position to the end when the text changes
DisposableEffect(Unit) {
textState.value = textState.value.copy(
selection = TextRange(textState.value.text.length)
)
onDispose { }
}
}
Upvotes: 4
Reputation: 189
An example of how to insert new text at the current position of the input cursor. And move the cursor to a new position
// TextField
var textFieldValue by remember { mutableStateOf(TextFieldValue("")) }
TextField(textFieldValue, onValueChange = { textFieldValue = it })
private fun insertText(textFieldValue: TextFieldValue, insertText: String): TextFieldValue {
val maxChars = textFieldValue.text.length
val textBeforeSelection = textFieldValue.getTextBeforeSelection(maxChars)
val textAfterSelection = textFieldValue.getTextAfterSelection(maxChars)
val newText = "$textBeforeSelection$insertText$textAfterSelection"
val newCursorPosition = textBeforeSelection.length + insertText.length
return TextFieldValue(
text = newText,
selection = TextRange(newCursorPosition)
)
}
// use
onClick = {
textFieldValue = insertText(textFieldValue, " #$tag")
}
Upvotes: 3
Reputation: 1080
We can use TextFieldValue
to change cursor position
Initialise the TextFieldValue
just like this
var textFieldValueState by remember {
mutableStateOf(
TextFieldValue(
text = ""
)
)
}
after initialising it set the TextFieldValue
just like the below
OutlinedTextField(
value = textFieldValueState,
onValueChange = { textFieldValueState = it },
...
)
To append additional text and for cursor selection, follow these steps
IconButton(modifier = Modifier.then(Modifier.size(48.dp)),
onClick = {
val value = textFieldValueState.text.plus("****")
textFieldValueState = TextFieldValue(
text = value,
selection = TextRange(value.length-2)
)
})
TextFieldValue
text
and selection
variables are not changeable so we need to create new TextFieldValue
to set the text and cursor position.
Upvotes: 56