I have textField composable and button composable. I want that clicking at the button would erase the text in the textField composable.
example:
var text by remember
mutableStateOf(TextFieldValue(""))}
TextField(
value = text,
onValueChange = { newValue -> text = newValue },
modifier = Modifier
.padding(8.dp),
)
Button(
onClick = {
//TODO: clean the text in textFiled
},
modifier = Modifier
.size(200.dp, 40.dp)
) {
Text(text = "erase textField"
}
thanks
You can just simply reset the value of the text mutableState:
Button(onClick = { text = TextFieldValue("") })
Create a mutableState as follows -> var textState by remember { mutableStateOf("") }
Create Textfield -> TextField(value = textState, onValueChange = { textState = it })
In the onClick of the button invoke the textState -> textState = ""
Related
I have an OutlineTextField where I am editing and updating it by calling an API on click of Save button.
Now what I want if the user doesn't change the text, api call should not happen and then onclick of save , there should not be any api call and it should got to the previous screen.
Below is my code snippet:
OutlinedTextField(
value = value,
modifier = modifier,
onValueChange = onValueChange,
placeholder = PlaceholderComponent
)
I solved it by checking initial viewmodel text.
If I've understood the question clearly, as #Gabriele Mariotti suggested, you can store the previous value of the text field and then compare it with the actual in the text field itself on the button click.
You can arrange the code with a Composable function like so:
#Composable
fun SaveButton(
modifier: Modifier = Modifier
) {
var currentValue by remember { mutableStateOf("") }
var previousValue by remember { mutableStateOf(currentValue) }
val context = LocalContext.current
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly,
modifier = Modifier.fillMaxSize()
) {
OutlinedTextField(
value = currentValue,
modifier = modifier,
onValueChange = {
currentValue = it
}
)
Button(onClick = {
if (currentValue != previousValue) {
Toast.makeText(context, "API request started", Toast.LENGTH_SHORT).show()
previousValue = currentValue
// Handle API request
} else {
Toast.makeText(context, "The text has not changed. Returning to the previous screen...", Toast.LENGTH_LONG).show()
// Handle on back screen
}
}) {
Text(text = "Save")
}
}
}
I am trying to figure out how to add a drawable to a text within a textfield (OutlinedTextField) but without any success. I have already created a drawable in the drawable folder. Do I need to create a seperate composable to insert it or can I directly add it inside the textfield ?
This is my textfield in the composable:
Spacer(modifier = Modifier.height(20.dp))
OutlinedTextField(
value = username.value,
onValueChange = { newText ->
username.value = newText
},
label = { Text(text = "Username") },
placeholder = { Text("") }, // placeholder / hint
modifier = Modifier
.fillMaxWidth(180F)
)
Use leadingIcon instead of placeHolder
OutlinedTextField(
value = username.value,
onValueChange = { newText ->
username.value = newText
},
label = { Text(text = "Username") },
leadingIcon = { Icon(imageVector = Icons.Default.Place, contentDescription = null)},
modifier = Modifier
.fillMaxWidth(180F)
)
This his how my composable looks like
#Composable
fun MyComposable(
email:String?,
onEmailChanged:(email)-> Unit,
buttonClicked:()->Unit,
validEmail:Boolean
){
val focusRequester = remember { FocusRequester() }
val focusManager = LocalFocusManager.current
val keyboardController = LocalSoftwareKeyboardController.current
TextField(
modifier = Modifier
.fillMaxWidth()
.focusRequester(focusRequester = focusRequester),
value = email ?: "",
status = someStatus // Default, Error, Success
onValueChange = { email -> onEmailChanged(email)},
)
Button(
onClick = {
focusManager.clearFocus()
buttonClicked()
if(!validEmail) focusRequester.requestFocus()
},
) {
Text(text = "Button")
}
}
}
I have added the basic code for explanation, i am facing issue with focusRequester when a button is clicked.
For accessibility reasons once the button is clicked, and if the email is invalid, i would like the focus to go back to TextField so that accessibility can announce it's state and label.
I tried clearing the focus and then requesting it again, but it only works for the first time. And i would like the TextField to gain focus every-time a button is clicked and email is invalid.
Am i missing something here?
try this it works totally fine.
#Composable
fun Test() {
val context = LocalContext.current
val emailState = remember { mutableStateOf("") }
val focusRequester = remember { FocusRequester() }
val focusManager = LocalFocusManager.current
Column {
TextField(
modifier = Modifier
.focusRequester(focusRequester)
.fillMaxWidth(),
value = emailState.value,
onValueChange = {
emailState.value = it
},
)
Button(onClick = {
focusManager.clearFocus()
if (emailState.value.isEmpty() ) {
focusRequester.requestFocus()
Toast.makeText(context, "error", Toast.LENGTH_SHORT).show()
}
}) { Text(text = "Button")
}
}
}
I couldn't find any way to get the focus back on TextField if it was already focused, once the button was clicked.
I ended up using live-region for announcement.
TextField(
modifier = Modifier
.fillMaxWidth()
.semantics {
liveRegion = LiveRegionMode.Assertive
}),
value = email ?: "",
status = someStatus // Default, Error, Success
onValueChange = { email -> onEmailChanged(email)},
)
Button(
onClick = {
focusManager.clearFocus()
buttonClicked()
},
) {
Text(text = "Button")
}
}
I am currently unable to capture user input in to a textfield when the KeyboardType of the keyboard is set to KeyboardType.Number.
If the keyboard is set to KeyboardType.Text, the Textfield updates as expected, however when set to KeyboardType.Number, the Textfield fails to update.
Why is this? and how can I change my code so that when the Textfield is clicked, a Number Keyboard is displayed ,and, when numbers are pressed, the relevant numbers are updated in the Textfield.
The following code DOES NOT update the textfield (When set to KeyboardType.Number)...
#Composable
fun MyNumberField() {
var text = remember { mutableStateOf("")}
val change : (String) -> Unit = { it ->
value.value = it
}
TextField(
value = text.value,
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
onValueChange = change
)
}
The following code does update the textfield (When set to KeyboardType.Text)...
#Composable
fun MyNumberField() {
var text = remember { mutableStateOf("")}
val change : (String) -> Unit = { it ->
text.value = it
}
TextField(
value = value.value,
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Text),
onValueChange = change
)
}
Many Thanks
You are supposed to update text.value, not value.value there is a typo in your code change it to this.
#Composable
fun MyNumberField() {
var text = remember { mutableStateOf("")}
val change : (String) -> Unit = { it ->
value.value = it // you have this which is not correct and I don't think it even compiled
text.value = it // it is supposed to be this
}
TextField(
value = text.value,
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
onValueChange = change
)
}
I want to create an auto complete text view in compose, and I created a composable that contains a TextField and a DropDown menu. The issue I'm seeing with this solution is that when the drop down menu is expanded the text field is no longer actionable, I can't type any text in it. Any suggestions on how to address this? The code is below
#Composable
fun AutoCompleteText(
value: String,
onValueChange: (String) -> Unit,
onOptionSelected: (String) -> Unit,
modifier: Modifier = Modifier,
label: #Composable (() -> Unit)? = null,
suggestions: List<String> = emptyList()
) {
Column(modifier = modifier) {
OutlinedTextField(
value = value,
onValueChange = { text -> if (text !== value) onValueChange(text) },
modifier = Modifier.fillMaxWidth(),
label = label,
)
DropdownMenu(
expanded = suggestions.isNotEmpty(),
onDismissRequest = { },
modifier = Modifier.fillMaxWidth()
) {
suggestions.forEach { label ->
DropdownMenuItem(onClick = {
onOptionSelected(label)
}) {
Text(text = label)
}
}
}
}
}
DropdownMenu has a property called PopupProperties that you can use to disable focusability. This should allow you to be able to continue typing in to the OutlinedTextField:
OutlinedTextField(
value = value,
onValueChange = { text -> if (text !== value) onValueChange(text) },
modifier = Modifier.fillMaxWidth(),
label = label,
)
DropdownMenu(
expanded = suggestions.isNotEmpty(),
onDismissRequest = { },
modifier = Modifier.fillMaxWidth(),
// This line here will accomplish what you want
properties = PopupProperties(focusable = false)
) {
suggestions.forEach { label ->
DropdownMenuItem(onClick = {
onOptionSelected(label)
}) {
Text(text = label)
}
}
}