I have input field defined like this:
BasicTextField(
keyboardOptions = KeyboardOptions(keyboardType=KeyboardType.Number),
value = text,
enabled = enabled,
singleLine = true,
textStyle = Theme.typography.Body16,
onValueChange = { onTextChange(it) },
modifier = Modifier
.fillMaxWidth(0.85f)
.onFocusChanged {
hasFocus = it.hasFocus
}
)
which allows to enter just numbers and display numeric keyboard. But users can paste any text. How to prevent pasting text ? or completely disable paste option ?
You can check if the new value is digits only
onValueChange = {
if (TextUtils.isDigitsOnly(it))
onTextChange(it)
}
Related
In Android emulator, entering input using Computer Keyboard, but the "Enter" key on my keyboard should take the input and do the action. Instead, the input is allowing me in the next line, and keep on continuing to the next line (as a new line character). Please suggest me your answers in Android Jetpack Composable of TextField element.
Hey you can use singleLine = true in text field, To perform any custom actions on click of Done/Enter Key in keyboard you can use something like
TextField(
value = text,
onValueChange = {text = it},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
onDone = { /* do something */},
onGo = { /* do something */},
onNext = { /* do something */},
onPrevious = { /* do something */},
onSearch = { /* do something */},
onSend = { /* do something */})
)
You can add singleLine = true to avoid the new line.
Also you can use the onKeyEvent modifier to intercept the ENTER and do a custom action. You can apply the same action also to the Done Key in keyboard using the KeyboardActions attribute.
Something like:
TextField(
value = text,
onValueChange = {text = it},
singleLine = true ,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
onDone = { /* do something */}
),
modifier = Modifier.onKeyEvent {
if (it.key == Key.Enter){
/* do something */
true
}
false
}
)
I have a compose OutlinedTextField which shouldn't be manually editable but filled using input from something that happens on clicking the text field. But setting the field as readOnly=true makes the clickable modifier not work. So a workaround I found is to set it as enabled=false which lets clickable work.
OutlinedTextField(
value = text,
onValueChange = { text = it},
enabled = false,
modifier = Modifier.clickable { text= "Clicked"}
)
How can I make this look as if its enabled based on whatever theme is being followed without setting a fixed color?
You can use the TextFieldDefaults.outlinedTextFieldColors applying in the disabled colors the same value of the enabled colors without using hardcoded values:
OutlinedTextField(
//...
enabled = false,
colors = TextFieldDefaults.outlinedTextFieldColors(
disabledTextColor = LocalContentColor.current.copy(LocalContentAlpha.current),
backgroundColor = Color.Transparent,
disabledBorderColor = MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled),
disabledLabelColor = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium),
)
)
Product: Android App
Programming language: kotlin
When using XML to create the UI. There is an option for a password field with the password visible to the user.
All the developer have to do is set the inputType = TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
In Jetpack Compose there is the option to create a textField(). Then pass in visualTransformation = PasswordVisualTransformation() to make the typing turn into dots. However, it does not preview the letters for a few seconds before turning into dots like how it was with XML.
Was wondering if there is an equivalent jetpack compose function of a password field with the password visible to the user for a few seconds before it turns into a dot.
Thank you
The inputType configures the keyboard type that is shown, acceptable characters and appearance of the edit text.
With 1.0.0 to have a Password field you can use a TextField with the KeyboardType.Password:
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
Check also this ticket for futher configuration.
To use a Password field with visualTransformation(mask character used instead of original text):
var password by rememberSaveable { mutableStateOf("") }
TextField(
value = password,
onValueChange = { password = it },
label = { Text("Enter password") },
visualTransformation = PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
)
To use a password field visible to the user, just remove the visualTransformation (and use the default VisualTransformation.None):
var password by rememberSaveable { mutableStateOf("") }
TextField(
value = password,
onValueChange = { password = it },
label = { Text("Enter password") },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
)
If you want to switch between the two options:
var passwordVisibility by remember { mutableStateOf(false) }
TextField(
//...
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
visualTransformation = if (passwordVisibility) VisualTransformation.None else PasswordVisualTransformation(),
)
In material design TextField page TextField has properties such as
Assistive elements provide additional detail about text entered into
text fields.
Helper text Helper text conveys additional guidance about the input field, such as how it will be used. It should only take up a single
line, being persistently visible or visible only on focus.
Error message When text input isn't accepted, an error message can display instructions on how to fix it. Error messages are displayed
below the input line, replacing helper text until fixed.
Icons Icons can be used to message alerts as well. Pair them with error messages to provide redundant alerts, which are useful when you
need to design for colorblind users.
Character counter Character or word counters should be used if there is a character or word limit. They display the ratio of
characters used and the total character limit.
Do these properties exist for Jetpack Compose TextField as of compose 1.0.0-alpha09?
With 1.0.x there aren't built-in properties to display an error message or the counter text.
However you can use a custom composable.
For the error message you can use something like:
var text by rememberSaveable { mutableStateOf("") }
var isError by rememberSaveable { mutableStateOf(false) }
fun validate(text: String) {
isError = /* .... */
}
Column {
TextField(
value = text,
onValueChange = {
text = it
isError = false
},
trailingIcon = {
if (isError)
Icon(Icons.Filled.Error,"error", tint = MaterialTheme.colors.error)
},
singleLine = true,
isError = isError,
keyboardActions = KeyboardActions { validate(text) },
)
if (isError) {
Text(
text = "Error message",
color = MaterialTheme.colors.error,
style = MaterialTheme.typography.caption,
modifier = Modifier.padding(start = 16.dp)
)
}
}
To display the counter text you can use something like:
val maxChar = 5
Column(){
TextField(
value = text,
onValueChange = {
if (it.length <= maxChar) text = it
},
modifier = Modifier.fillMaxWidth()
)
Text(
text = "${text.length} / $maxChar",
textAlign = TextAlign.End,
style = MaterialTheme.typography.caption,
modifier = Modifier.fillMaxWidth().padding(end = 16.dp)
)
}
trailingIcon for the icon.
For the text at the bottom I just used
Text(
text = "Error message",
color = MaterialTheme.colors.error,
style = MaterialTheme.typography.caption,
modifier = Modifier.padding(start = 16.dp)
)
Might be included in the future? Weirdly enough the documentation for isError says:
indicates if the text field's current value is in error. If set to
true, the label, bottom indicator and trailing icon by default will
be displayed in error color
What bottom indicator? There is no such thing. Weird.
Is there a way to disable all interaction for Jetpack Compose's TextField?
You can use the enabled attribute:
enabled : controls the enabled state of the TextField. When false, the text field will be neither editable nor focusable, the input of the text field will not be selectable, visually text field will appear in the disabled UI state
Something like:
var text by rememberSaveable { mutableStateOf("Text") }
TextField(
value = text,
onValueChange = { text = it },
enabled = false,
label = { Text("Label") },
singleLine = true
)
My project is on alpha08 atm. Hopefully they add some built in way of doing this soon but in the meantime I've been doing this:
val textState = remember { mutableStateOf(TextFieldValue()) }
val disabled = remember { mutableStateOf(true) }
Box {
TextField(value = textState.value, onValueChange = {
textState.value = it
})
if (disabled.value) {
// Set alpha(0f) to hide click animation
Box(modifier = Modifier.matchParentSize().alpha(0f).clickable(onClick = {}))
}
}
So yeah, drawing an invisible clickable Box that's the same size over the TextField. You can resize the TextField to whatever you'd want, calling .matchParentSize() on the invisible Box will make it match the TextField due to them being the only children in the parent Box.
You can toggle the disabled state by setting disabled.value = true/false wherever is appropriate.
readOnly attribute can also work in case if you want focusable & selectable text field but not editable.
Like this:
var value by remember { mutableStateOf("Hello World!") }
TextField(
value = value,
onValueChange = { value = it },
readOnly = true,
)