2. Nov 2021Android

Jetpack Compose Basics - How to use text field composables to meet the Material design specification

Text field is UI component that allow users to enter textual information into a UI, typically in forms. Text fields in Material design come in two types: Filled text fields or Outlined text fields. Both provide the same functionality, so your choice should be based on style preferences. It is not recommended to mix them.

Peter ŠulyAndroid developer

Both text field types consist of container (1), optional leading icon (2), label (3), input text (4), optional trailing icon (5), activation indicator (6) and optional helper text (7)

Outlined text field in Jetpack Compose

Compose provides OutlinedTextField composable to fulfill Material specification of outlined text field. Without further customisation OutlinedTextField composable looks like this

This composable has around 20 parameters but only 2 of them are mandatory.

  • value - text shown in text field
  • onValueChange - callback triggered when the input service updates the text which comes as parameter of callback
fun OutlinedTextField(
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = LocalTextStyle.current,
    label: @Composable (() -> Unit)? = null,
    placeholder: @Composable (() -> Unit)? = null,
    leadingIcon: @Composable (() -> Unit)? = null,
    trailingIcon: @Composable (() -> Unit)? = null,
    isError: Boolean = false,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions.Default,
    singleLine: Boolean = false,
    maxLines: Int = Int.MAX_VALUE,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    shape: Shape = MaterialTheme.shapes.small,
    colors: TextFieldColors = TextFieldDefaults.outlinedTextFieldColors()

Optional parameters which can customize text field are

  • modifier - used for changes from the caller side
  • enabled - boolean which controls if text field is in enabled state. When enabled is false text field is not editable, focusable or selectable
  • readOnly - when parameter is true, text in field can be focued and user can copy it but cannot modify it
  • textStyle - style of input text. Can be easily modified e.g. like this
  • label - label to be displayed inside container or when in focused state on the top of container. Can be used like this
label = { Text(text = "Label for text") }
  • placeholder - placeholder to be displayed when field is empty
placeholder = { Text(text = "Placeholder for text") }


  • leadingIcon - composable to be displayed at the beginning of the field
leadingIcon = { Icon(imageVector = Icons.Default.Info, contentDescription = "") }


leadingIcon = { Text(text = "$") }
  • trailingIcon - basically the same as leadingIcon but at the end of the field
  • isError - indicates if current text value is in error state. If set to true error label and trailing icon is shown tinted to error color. If there is no label and trailing icon specified, only container is tinted to error color
  • visualTransformation - transforms visual representation of input value, for example showing '*' when password is written. For this use-case there is PasswordVisualTransformation but it's simple to implement your own one
visualTransformation = PasswordVisualTransformation()
  • keyboardOptions - SW keyboard options used for configuring KeyboardType, ImeAction and others
keyboardOptions = KeyboardOptions.Default.copy(
    capitalization = KeyboardCapitalization.Words,
    autoCorrect = false,
    keyboardType = KeyboardType.Text,
    imeAction = ImeAction.Search
  • keyboardActions - when input service emits an action, corresponding callback is called
keyboardActions = KeyboardActions(
    onAny = {} // do when ANY of ime actions is emitted


keyboardActions = KeyboardActions(
    onDone = {}, // do when SPECIFIED action is emitted
    onSearch = {},
  • singleLine - whether text should be only on single line with horizontal scroll. maxLines parameter is ignored if singleLine is true
  • maxLines - maximum number of lines
  • interactionSource - MutableInteractionSource representing the stream of interactions for this composable. Can be used if you want to observe Interactions and customize appearance or behavior of composable
  • shape - shape of fields border
  • colors - instance of TextFieldColors object controlling color of parts of field. These can be easily changed like this
colors = TextFieldDefaults.outlinedTextFieldColors(
    focusedBorderColor = Color.Yellow,
    leadingIconColor = Color.Yellow

Filled text field in Jetpack Compose

Compose provides TextField composable to fulfill Material specification of filled text field. Without further customization TextField composable looks like this

All parameters of TextField composable function are the same as for OutlinedTextField (except different shape and colors) and have the same usage.

TextField with enabled as false

TextField with label

TextField with leading icon

TextField in error state

More articles from the Jetpack Compose Basics series:

Peter ŠulyAndroid developer