Skip to main content

Implementing Clear Button in Jetpack Compose TextField

Jetpack Compose, Android’s modern UI toolkit, has revolutionized how developers build user interfaces. One of its many strengths is the simplicity and flexibility it offers when implementing UI components. However, certain common features, like a clear button for TextField, require some custom implementation. In this blog post, we’ll explore how to implement a clear button in a TextField using Jetpack Compose.

Why Add a Clear Button?

A clear button improves user experience by allowing users to quickly erase the text in a field with a single tap. It’s especially useful in search bars, forms, or any input field where users might want to reset their input easily.

Jetpack Compose provides a robust TextField API, but it doesn’t include a built-in clear button. Fortunately, Compose’s flexibility allows us to create one with ease.

Prerequisites

Before diving into the implementation, ensure you’re familiar with:

  • Basics of Jetpack Compose

  • State management in Compose

  • Modifier usage in Compose UI

Let’s get started!

Step 1: Setting Up a Basic TextField

Start with a simple TextField that uses a state variable to hold the user’s input.

import androidx.compose.runtime.*
import androidx.compose.material.*
import androidx.compose.foundation.layout.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

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

    TextField(
        value = text,
        onValueChange = { text = it },
        modifier = Modifier.fillMaxWidth(),
        placeholder = { Text("Enter text") }
    )
}

This basic implementation displays a TextField with a placeholder. Users can input text, and the state is updated accordingly.

Step 2: Adding the Clear Button

To add a clear button, we’ll use the trailingIcon parameter of the TextField. This parameter allows us to define an icon displayed at the end of the TextField.

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

    TextField(
        value = text,
        onValueChange = { text = it },
        modifier = Modifier.fillMaxWidth(),
        placeholder = { Text("Enter text") },
        trailingIcon = {
            if (text.isNotEmpty()) {
                IconButton(onClick = { text = "" }) {
                    Icon(
                        imageVector = Icons.Default.Close,
                        contentDescription = "Clear text"
                    )
                }
            }
        }
    )
}

Key Points:

  • The trailingIcon parameter checks if the text is not empty. If it isn’t, a clear button (an Icon) is displayed.

  • When the button is clicked, the text is cleared by resetting the state.

Step 3: Customizing the Clear Button

While the default close icon works, you can customize it to better fit your app’s design. For example:

Custom Icon

Replace the default icon with a custom one:

Icon(
    painter = painterResource(id = R.drawable.ic_clear),
    contentDescription = "Clear text",
    tint = Color.Gray
)

Animating the Clear Button

Add animations to make the clear button appear and disappear smoothly:

import androidx.compose.animation.*

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

    TextField(
        value = text,
        onValueChange = { text = it },
        modifier = Modifier.fillMaxWidth(),
        placeholder = { Text("Enter text") },
        trailingIcon = {
            AnimatedVisibility(visible = text.isNotEmpty()) {
                IconButton(onClick = { text = "" }) {
                    Icon(
                        imageVector = Icons.Default.Close,
                        contentDescription = "Clear text"
                    )
                }
            }
        }
    )
}

Step 4: Improving Accessibility

Accessibility is crucial for creating inclusive apps. Use meaningful contentDescription values for the clear button:

Icon(
    imageVector = Icons.Default.Close,
    contentDescription = "Clear text input"
)

This ensures that screen readers can announce the purpose of the button to users.

Step 5: Handling Edge Cases

Long Text Input

For long inputs, ensure the clear button doesn’t overlap the text. Use padding and alignment to adjust its position:

TextField(
    value = text,
    onValueChange = { text = it },
    modifier = Modifier
        .fillMaxWidth()
        .padding(end = 8.dp),
    trailingIcon = { /* Clear Button */ }
)

Large Touch Targets

Make the button’s touch target large enough to comply with accessibility guidelines:

IconButton(
    onClick = { text = "" },
    modifier = Modifier.size(48.dp)
) {
    Icon(
        imageVector = Icons.Default.Close,
        contentDescription = "Clear text"
    )
}

Best Practices for Clear Button Implementation

  1. Show the Clear Button Only When Necessary: Display the button only when the TextField contains text.

  2. Provide Meaningful Feedback: Ensure the button clears the input instantly and updates the UI.

  3. Maintain Visual Consistency: Customize the button to match your app’s theme.

  4. Optimize for Accessibility: Use descriptive contentDescription values and ensure the button is easy to tap.

Conclusion

Adding a clear button to a TextField in Jetpack Compose enhances the user experience and demonstrates the power of Compose’s flexibility. By leveraging features like trailingIcon and AnimatedVisibility, you can create a polished and responsive clear button that aligns with your app’s design and functionality.

With Jetpack Compose, implementing such features is not just easy but also fun. Start experimenting with your own variations to further customize the experience.

Happy Composing!

Popular posts from this blog

Restricting Jetpack Compose TextField to Numeric Input Only

Jetpack Compose has revolutionized Android development with its declarative approach, enabling developers to build modern, responsive UIs more efficiently. Among the many components provided by Compose, TextField is a critical building block for user input. However, ensuring that a TextField accepts only numeric input can pose challenges, especially when considering edge cases like empty fields, invalid characters, or localization nuances. In this blog post, we'll explore how to restrict a Jetpack Compose TextField to numeric input only, discussing both basic and advanced implementations. Why Restricting Input Matters Restricting user input to numeric values is a common requirement in apps dealing with forms, payment entries, age verifications, or any data where only numbers are valid. Properly validating input at the UI level enhances user experience, reduces backend validation overhead, and minimizes errors during data processing. Compose provides the flexibility to implement ...

jetpack compose - TextField remove underline

Compose TextField Remove Underline The TextField is the text input widget of android jetpack compose library. TextField is an equivalent widget of the android view system’s EditText widget. TextField is used to enter and modify text. The following jetpack compose tutorial will demonstrate to us how we can remove (actually hide) the underline from a TextField widget in an android application. We have to apply a simple trick to remove (hide) the underline from the TextField. The TextField constructor’s ‘colors’ argument allows us to set or change colors for TextField’s various components such as text color, cursor color, label color, error color, background color, focused and unfocused indicator color, etc. Jetpack developers can pass a TextFieldDefaults.textFieldColors() function with arguments value for the TextField ‘colors’ argument. There are many arguments for this ‘TextFieldDefaults.textFieldColors()’function such as textColor, disabledTextColor, backgroundColor, cursorC...

jetpack compose - Image clickable

Compose Image Clickable The Image widget allows android developers to display an image object to the app user interface using the jetpack compose library. Android app developers can show image objects to the Image widget from various sources such as painter resources, vector resources, bitmap, etc. Image is a very essential component of the jetpack compose library. Android app developers can change many properties of an Image widget by its modifiers such as size, shape, etc. We also can specify the Image object scaling algorithm, content description, etc. But how can we set a click event to an Image widget in a jetpack compose application? There is no built-in property/parameter/argument to set up an onClick event directly to the Image widget. This android application development tutorial will demonstrate to us how we can add a click event to the Image widget and make it clickable. Click event of a widget allow app users to execute a task such as showing a toast message by cli...