EditText to TextField
The main way for inputting text through user input in Compose is via TextField
. As opposed to the EditText
, this composable does not hold a reference to the value it renders. Instead it accepts the value it needs to display as a parameter. Similarly, is accepts a callback for when the text changes.
Both TextField
and its variant OutlinedTextField
support all stylistic options that appear on Google's Material Guidelines. This includes hints, outlines, leading and trailing icons.
A third variant of EditText
also exists, called BasicTextField
. This composable can be used for text input without any stylistic options. This is useful in cases you need additional customization freedom in your text input.
How to listen to text changes (TextChangedListener)
The TextField
composable requires the text to render via the text parameter.
Once new text is input from the keyboard, the onTextChange
is called with the updated value. You can then use the updated value to update the composable:
var text by remember { mutableStateOf("") }
TextField(
value = text,
onValueChange = {
// new text has been input
text = it
}
)
Normally, you would keep that value within a ViewModel
. Once the new value is received you will forward the value back to the ViewModel, similarly to how you would normally do it using Views.
In the above example, the text is stored as a MutableState
within the composable for simplicity.
How to change the text style of an TextField (text colors, fonts, etc)
Similar to Text
a TextField
accepts a textStyle
which is used to customize the looks of the displayed text.
var text by remember { mutableStateOf("") }
TextField(
textStyle = TextStyle(
fontFamily = FontFamily.Monospace
),
value = text,
onValueChange = {
text = it
}
)
The above sample causes the TextField
to render its text using the Monospace font.
How to specify the input type (phone numbers, e-mails, text, digits)
You can specify the expected input type of the TextField
via the keyboardOptions
parameter. This will request the selected soft-keyboard to display the best keyboard layout for the job.
The following example asks the soft-keyboard for a dial-pad layout, which will prompt the soft-keyboard to display a dial-pad layout.
var text by remember { mutableStateOf("") }
TextField(
value = text,
onValueChange = {
text = it
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Phone
)
)
How to specify and handle IME action (change ENTER to Done, Search, Next, etc)
The keyboardOptions
parameter accepts an ImeAction
. Depending on the value you provide, the soft-keyboard will display a different action instead of the return key.
By default, the return key will do nothing once pressed.
You can receive callbacks regarding keyboard actions via the keyboardActions
parameter. You can specify actions for different events (such as onDone
, onNext
, onSearch
, etc). Unless you need to handle a complicated scenario, the KeyboardActions
provide an onAny
callback.
var address by remember { mutableStateOf("") }
TextField(
value = address,
onValueChange = {
address = it
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email,
imeAction = ImeAction.Search
)
)
How to listen to specific key press events
Use the onKeyEvent
modifier to observe specific key press events. It works similarly to Views.setOnKeyListener()
. It provides a KeyEvent
with information about the key that was pressed (or released).
var text by remember { mutableStateOf("") }
TextField(
modifier = Modifier.onKeyEvent { keyEvent ->
if (keyEvent.type == KeyEventType.KeyUp
&& keyEvent.key == Key.Backspace
) {
// Backspace was pressed.
// consume the event by returning 'true'
true
} else {
false
}
},
value = text,
onValueChange = {
text = it
}
)
How to request focus
The TextField
composables will not request focus by default as opposed to EditText
.
You need a reference to a FocusRequester()
which provides the API for capturing focus. It is up to you to request focus when needed.
The following snippet tries to replicate the EditText
's automatic way of receiving focus. The difference is that the focus will be requested only the first time the composable enters composition.
val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) {
focusRequester.requestFocus()
}
var value by remember { mutableStateOf("") }
TextField(
modifier = Modifier.focusRequester(focusRequester),
value = value,
onValueChange = {
value = it
},
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Done
),
)
How to control keyboard focus
The FocusManager
is the main API for controlling the direction of focus. You gain access to the API by using the respective composition local and controlling the focus on the appropriate callback.
The following sample showcases how to move focus from a first TextField
to the second when the IME action is pressed. The last TextField
will clear focus when the IME action is pressed.
Column {
val focusManager = LocalFocusManager.current
var value by remember { mutableStateOf("") }
TextField(
value = value,
onValueChange = {
value = it
},
singleLine = true,
keyboardActions = KeyboardActions {
focusManager.moveFocus(FocusDirection.Next)
},
)
TextField(
value = value,
onValueChange = {
value = it
},
singleLine = true,
keyboardActions = KeyboardActions {
focusManager.clearFocus(force = true)
},
)
}
How to show the soft-keyboard
The soft-keyboard will be automatically show as soon as a TextField
is focused. Check how to request focus for a code sample.
How to hide the soft-keyboard
The soft-keyboard will be automatically dismissed when focus is cleared. The following sample clears focus when the IME action is pressed:
val focusManager = LocalFocusManager.current
var value by remember { mutableStateOf("") }
TextField(
value = value,
onValueChange = {
value = it
},
singleLine = true,
keyboardActions = KeyboardActions {
focusManager.clearFocus(force = true)
},
)
How to customize the style of your TextField (border, colors, etc)
You can modify the shape of your TextField
by using the shape
parameter. For example passing a RoundedCornerShape(20.dp)
will render a TextField
with rounded corners with a radius of 20 dp.
The colors of the TextField
are controlled by the color
parameter. It allows you to specify colors of very particular parts of your TextField
such as its contents, background or cursor color. To make this easier, you can use the TextFieldDefaults
functions for the default colors of the respective TextField
.
var value by remember { mutableStateOf("") }
OutlinedTextField(
shape = CircleShape,
colors = TextFieldDefaults.textFieldColors(
backgroundColor =
MaterialTheme.colors.primary.copy(alpha = 0.12f),
),
value = value,
onValueChange = {
value = it
},
)
When styling your composables, prefer using colors via the current theme. You can gain access to the colors of your theme by using the
MaterialTheme.colors
object.
How to change colors of your TextField
Use the colors
parameter to specify colors such as the text color, cursor color, error color and more.
Use the functions of the TextFieldDefaults
object for default values:
var text by remember { mutableStateOf("") }
TextField(
value = text,
onValueChange = {
text = it
},
colors = TextFieldDefaults.textFieldColors(
cursorColor = Color.Magenta,
trailingIconColor = Color.LightGray,
backgroundColor = Color.Transparent
),
trailingIcon = {
Icon(Icons.Rounded.Info, contentDescription = null)
}
)
How to display an error to your TextField
Pass true
to the isError parameter to signify that the TextField
is in error state. This will make the trailing icon, label and bottom indicator to be tinted in the error color:
var text by remember { mutableStateOf("") }
TextField(
value = text,
onValueChange = {
text = it
},
isError = text.isEmpty(),
trailingIcon = {
Icon(Icons.Rounded.Edit, contentDescription = null)
}
)
Am I forced to use the Material Guidelines looks for my InputText
If TextField
and OutlinedTextField
might not fit the style of your application's design, you can use BasicTextField
to match your preferred looks.