EditText in Jetpack Compose: A Complete Guide

EditText in Jetpack Compose: A Complete Guide

Jetpack Compose introduces a new way to handle user input with a composable called TextField, which replaces the traditional EditText used in XML-based layouts. TextField is used to capture user input and allows for easy customization and styling. This guide will cover the basics of TextField, how to manage input state, and various customization options in Jetpack Compose.


What is TextField in Jetpack Compose?

In Jetpack Compose, TextField serves as the primary component for accepting text input from users, similar to EditText in the traditional Android XML layout system. It is designed to be simple yet flexible, allowing developers to customize its look and behavior extensively.

@Composable
fun SimpleTextField() {
    var text by remember { mutableStateOf("") }

    TextField(
        value = text,
        onValueChange = { newText ->
            text = newText
        },
        label = { Text("Enter your text") }
    )
}

Basic Properties of TextField

The TextField composable comes with several essential properties that allow developers to control its behavior and appearance:

  • value: The current text to display in the TextField. This is a state variable, typically a String.
  • onValueChange: A lambda function that’s triggered every time the text changes.
  • label: An optional composable to display a label inside the TextField.
  • placeholder: Shows placeholder text when the field is empty.
  • leadingIcon and trailingIcon: Icons placed on the left or right side of the TextField.

Handling State in TextField

In Jetpack Compose, handling state is critical. TextField requires a MutableState object to keep track of the input value. This is usually managed using the remember and mutableStateOf functions.

@Composable
fun StatefulTextField() {
    var inputText by remember { mutableStateOf("") }

    TextField(
        value = inputText,
        onValueChange = { newText ->
            inputText = newText
        },
        label = { Text("Name") }
    )
}

Customizing TextField Appearance

The TextField composable allows for extensive customization of its appearance. Here are some common styling options:

  1. Text Color: Customizes the color of the text within the TextField.
  2. Text Style: Allows setting font size, weight, and family.
  3. Background Color: Adds a background to the TextField.
  4. Shape: Modifies the shape of the TextField, such as rounded corners.
@Composable
fun StyledTextField() {
    var inputText by remember { mutableStateOf("") }

    TextField(
        value = inputText,
        onValueChange = { inputText = it },
        label = { Text("Email Address") },
        colors = TextFieldDefaults.textFieldColors(
            backgroundColor = Color.LightGray,
            focusedIndicatorColor = Color.Blue,
            unfocusedIndicatorColor = Color.Gray,
            textColor = Color.Black
        ),
        shape = RoundedCornerShape(8.dp),
        textStyle = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Bold)
    )
}

Adding Icons to TextField

You can easily add icons within a TextField using leadingIcon and trailingIcon properties. This is useful for fields that require indicators or action buttons (e.g., a search or clear button).

@Composable
fun TextFieldWithIcon() {
    var text by remember { mutableStateOf("") }

    TextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Search") },
        leadingIcon = { Icon(Icons.Default.Search, contentDescription = null) },
        trailingIcon = {
            if (text.isNotEmpty()) {
                IconButton(onClick = { text = "" }) {
                    Icon(Icons.Default.Clear, contentDescription = "Clear text")
                }
            }
        }
    )
}

Password Field with Obscured Text

To create a password input field, set visualTransformation to PasswordVisualTransformation(). This obscures the text to ensure privacy.

@Composable
fun PasswordTextField() {
    var password by remember { mutableStateOf("") }
    var isPasswordVisible by remember { mutableStateOf(false) }

    TextField(
        value = password,
        onValueChange = { password = it },
        label = { Text("Password") },
        visualTransformation = if (isPasswordVisible) VisualTransformation.None else PasswordVisualTransformation(),
        trailingIcon = {
            IconButton(onClick = { isPasswordVisible = !isPasswordVisible }) {
                Icon(
                    imageVector = if (isPasswordVisible) Icons.Default.Visibility else Icons.Default.VisibilityOff,
                    contentDescription = if (isPasswordVisible) "Hide password" else "Show password"
                )
            }
        }
    )
}

Outlined TextField

Compose provides OutlinedTextField, a variant with an outlined style similar to the Material Design guidelines. This type of text field is helpful when you want a more emphasized border around the input.

@Composable
fun OutlinedTextFieldExample() {
    var text by remember { mutableStateOf("") }

    OutlinedTextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Outlined Text Field") },
        leadingIcon = { Icon(Icons.Default.Email, contentDescription = null) }
    )
}

Controlling Text Input Types

You can specify the type of input for a TextField, such as numeric, email, or password, using the keyboardOptions property. The keyboardType within KeyboardOptions adjusts the keyboard accordingly.

@Composable
fun NumberInputTextField() {
    var number by remember { mutableStateOf("") }

    TextField(
        value = number,
        onValueChange = { number = it },
        label = { Text("Enter Number") },
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
    )
}

Error Handling in TextField

To display errors in a TextField, use conditional logic to show an error message based on validation criteria.

@Composable
fun TextFieldWithError() {
    var text by remember { mutableStateOf("") }
    var isError by remember { mutableStateOf(false) }

    Column {
        TextField(
            value = text,
            onValueChange = {
                text = it
                isError = text.length < 5
            },
            label = { Text("Username") },
            isError = isError
        )

        if (isError) {
            Text(
                text = "Username must be at least 5 characters",
                color = Color.Red,
                style = TextStyle(fontSize = 12.sp)
            )
        }
    }
}

Single-line vs Multi-line TextField

In Jetpack Compose, you can control the number of lines with singleLine or by setting maxLines. For multi-line input, specify the maxLines property.

@Composable
fun MultilineTextField() {
    var text by remember { mutableStateOf("") }

    TextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Multi-line Input") },
        maxLines = 5
    )
}

Keyboard Actions in TextField

TextField supports keyboard actions, allowing users to control what happens when they press “Done,” “Next,” or other action buttons. You can handle this with keyboardActions.

@Composable
fun KeyboardActionsTextField() {
    var text by remember { mutableStateOf("") }

    TextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Email") },
        keyboardOptions = KeyboardOptions(
            keyboardType = KeyboardType.Email,
            imeAction = ImeAction.Done
        ),
        keyboardActions = KeyboardActions(
            onDone = { /* Handle action */ }
        )
    )
}

Conclusion

The TextField composable in Jetpack Compose provides powerful, flexible options for creating user input fields without the complexity of XML layouts. From basic input to password fields, error handling, and custom styling, TextField covers all the typical use cases for text input in modern Android apps.

By leveraging the declarative approach of Jetpack Compose, developers can create rich and interactive text input fields that are both easy to implement and maintain. Mastering TextField is an essential skill for any developer working with Jetpack Compose.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top