Text fields allow users to enter text into a UI.
DenseTextFieldContentPadding
@Preview
@Composable
fun DenseTextFieldContentPadding() {
TextField(
state = rememberTextFieldState(),
lineLimits = TextFieldLineLimits.SingleLine,
label = { Text("Label") },
// Need to set a min height using `heightIn` to override the default
modifier = Modifier.heightIn(min = 48.dp),
contentPadding = PaddingValues(top = 4.dp, bottom = 4.dp, start = 12.dp, end = 12.dp),
)
}
SimpleTextFieldSample
@Preview
@Composable
fun SimpleTextFieldSample() {
TextField(
state = rememberTextFieldState(),
lineLimits = TextFieldLineLimits.SingleLine,
label = { Text("Label") },
)
}
TextFieldWithErrorState
@Preview
@Composable
fun TextFieldWithErrorState() {
val errorMessage = "Text input too long"
val state = rememberTextFieldState()
var isError by rememberSaveable { mutableStateOf(false) }
val charLimit = 10
fun validate(text: CharSequence) {
isError = text.length > charLimit
}
LaunchedEffect(Unit) {
// Run validation whenever text value changes
snapshotFlow { state.text }.collect { validate(it) }
}
TextField(
state = state,
lineLimits = TextFieldLineLimits.SingleLine,
label = { Text(if (isError) "Username*" else "Username") },
supportingText = {
Row {
Text(if (isError) errorMessage else "", Modifier.clearAndSetSemantics {})
Spacer(Modifier.weight(1f))
Text("Limit: ${state.text.length}/$charLimit")
}
},
isError = isError,
onKeyboardAction = { validate(state.text) },
modifier =
Modifier.semantics {
maxTextLength = charLimit
// Provide localized description of the error
if (isError) error(errorMessage)
},
)
}
TextFieldWithHideKeyboardOnImeAction
@Preview
@Composable
fun TextFieldWithHideKeyboardOnImeAction() {
val keyboardController = LocalSoftwareKeyboardController.current
TextField(
state = rememberTextFieldState(),
label = { Text("Label") },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
onKeyboardAction = { keyboardController?.hide() },
)
}
TextFieldWithIcons
@Preview
@Composable
fun TextFieldWithIcons() {
val state = rememberTextFieldState()
TextField(
state = state,
lineLimits = TextFieldLineLimits.SingleLine,
label = { Text("Label") },
leadingIcon = { Icon(Icons.Filled.Favorite, contentDescription = null) },
trailingIcon = {
TooltipBox(
positionProvider =
TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
tooltip = { PlainTooltip { Text("Clear text") } },
state = rememberTooltipState(),
) {
IconButton(onClick = { state.clearText() }) {
Icon(Icons.Filled.Clear, contentDescription = "Clear text")
}
}
},
)
}
TextFieldWithInitialValueAndSelection
@Preview
@Composable
fun TextFieldWithInitialValueAndSelection() {
val state = rememberTextFieldState("Initial text", TextRange(0, 12))
TextField(state = state, lineLimits = TextFieldLineLimits.SingleLine, label = { Text("Label") })
}
TextFieldWithPlaceholder
@Preview
@Composable
fun TextFieldWithPlaceholder() {
var alwaysMinimizeLabel by remember { mutableStateOf(false) }
Column {
Row {
Checkbox(checked = alwaysMinimizeLabel, onCheckedChange = { alwaysMinimizeLabel = it })
Text("Show placeholder even when unfocused")
}
Spacer(Modifier.height(16.dp))
TextField(
state = rememberTextFieldState(),
lineLimits = TextFieldLineLimits.SingleLine,
label = { Text("Email") },
labelPosition = TextFieldLabelPosition.Attached(alwaysMinimize = alwaysMinimizeLabel),
placeholder = { Text("[email protected]") },
)
}
}
TextFieldWithPrefixAndSuffix
@Preview
@Composable
fun TextFieldWithPrefixAndSuffix() {
var alwaysMinimizeLabel by remember { mutableStateOf(false) }
Column {
Row {
Checkbox(checked = alwaysMinimizeLabel, onCheckedChange = { alwaysMinimizeLabel = it })
Text("Show placeholder even when unfocused")
}
Spacer(Modifier.height(16.dp))
TextField(
state = rememberTextFieldState(),
lineLimits = TextFieldLineLimits.SingleLine,
label = { Text("Label") },
labelPosition = TextFieldLabelPosition.Attached(alwaysMinimize = alwaysMinimizeLabel),
prefix = { Text("www.") },
suffix = { Text(".com") },
placeholder = { Text("google") },
)
}
}
TextFieldWithSupportingText
@Preview
@Composable
fun TextFieldWithSupportingText() {
TextField(
state = rememberTextFieldState(),
lineLimits = TextFieldLineLimits.SingleLine,
label = { Text("Label") },
supportingText = {
Text("Supporting text that is long and perhaps goes onto another line.")
},
)
}
TextFieldWithTransformations
@Preview
@Composable
fun TextFieldWithTransformations() {
TextField(
state = rememberTextFieldState(),
lineLimits = TextFieldLineLimits.SingleLine,
label = { Text("Phone number") },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
// Input transformation to limit user input to 10 digits
inputTransformation =
InputTransformation.maxLength(10).then {
if (!this.asCharSequence().isDigitsOnly()) {
revertAllChanges()
}
},
outputTransformation = {
// Output transformation to format as a phone number: (XXX) XXX-XXXX
if (length > 0) insert(0, "(")
if (length > 4) insert(4, ") ")
if (length > 9) insert(9, "-")
},
)
}