Jetpack Compose has revolutionized Android development by providing a declarative UI framework that simplifies and accelerates the development process. Among its many features, TextField is one of the most commonly used components, enabling developers to implement user-friendly input fields. A frequent requirement in modern apps is to include a fixed suffix in a TextField, such as units (e.g., "kg" or "%") or static text (e.g., ".com"). In this blog post, we’ll explore how to implement a fixed suffix in Jetpack Compose's TextField while maintaining a clean and reusable approach.
Why Add a Fixed Suffix to a TextField?
Adding a fixed suffix can improve the user experience in several ways:
Clarity: Indicates the expected format of the input, such as "Amount in USD ($)."
Guidance: Provides context for user input, reducing errors.
Consistency: Enhances the visual consistency of the UI, especially in forms.
Now, let’s dive into the implementation details of this feature.
Prerequisites
Before we proceed, ensure you have the following:
Android Studio Bumblebee or later.
Knowledge of Kotlin and Jetpack Compose.
Jetpack Compose library set up in your project (latest stable version recommended).
Here’s a minimal build.gradle setup for Jetpack Compose:
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdk 34
defaultConfig {
applicationId "com.example.suffixtextfield"
minSdk 21
targetSdk 34
versionCode 1
versionName "1.0"
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion '1.5.3'
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation "androidx.compose.ui:ui:1.6.0"
implementation "androidx.compose.material:material:1.6.0"
implementation "androidx.compose.ui:ui-tooling:1.6.0"
implementation "androidx.compose.runtime:runtime-livedata:1.6.0"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.1"
}Implementing a Fixed Suffix in TextField
Jetpack Compose’s TextField does not have a built-in option for suffixes. However, we can achieve this by leveraging the Row composable to combine a TextField and a Text element that serves as the suffix. Here’s how:
Basic Implementation
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
@Composable
fun FixedSuffixTextField(placeholder: String, suffix: String) {
var text by remember { mutableStateOf("") }
Row(modifier = Modifier.fillMaxWidth()) {
TextField(
value = text,
onValueChange = { text = it },
placeholder = { Text(placeholder) },
modifier = Modifier.weight(1f)
)
Text(
text = suffix,
modifier = Modifier.padding(start = 8.dp, top = 16.dp),
style = MaterialTheme.typography.bodyMedium
)
}
}Key Points
Row Layout: The
Rowcomposable ensures theTextFieldand suffix align horizontally.Weight Modifier: The
TextFieldis given a weight of1fto occupy the remaining space, while theTextfor the suffix adjusts dynamically.Padding: Proper padding is applied to the suffix to maintain alignment with the input text.
Preview Example
Here’s a preview of the composable in action:
@Preview
@Composable
fun PreviewFixedSuffixTextField() {
MaterialTheme {
FixedSuffixTextField(placeholder = "Enter value", suffix = "%")
}
}Advanced Features
Supporting Outlined TextField
If you’re using OutlinedTextField for a more modern UI, the implementation remains similar. Simply replace TextField with OutlinedTextField:
OutlinedTextField(
value = text,
onValueChange = { text = it },
placeholder = { Text(placeholder) },
modifier = Modifier.weight(1f)
)Customizing Suffix Style
To enhance the appearance of the suffix, you can customize its style:
Text(
text = suffix,
modifier = Modifier.padding(start = 8.dp, top = 16.dp),
style = MaterialTheme.typography.bodyMedium.copy(
color = MaterialTheme.colorScheme.primary
)
)Handling Long Input Text
To ensure the suffix remains visible with long text inputs, use the maxLines parameter and scrollable modifier in the TextField:
TextField(
value = text,
onValueChange = { text = it },
placeholder = { Text(placeholder) },
modifier = Modifier
.weight(1f)
.horizontalScroll(rememberScrollState()),
maxLines = 1
)Best Practices
Validation: Ensure the suffix does not interfere with user input validation.
Localization: If the suffix changes based on locale (e.g., currency symbols), handle localization appropriately.
Accessibility: Use content descriptions to make the UI accessible for screen readers.
Wrapping Up
Adding a fixed suffix to a TextField in Jetpack Compose is straightforward yet powerful for improving usability. By combining composables like Row, TextField, and Text, you can create a flexible and visually appealing UI component. With the advanced features outlined above, you can further customize and optimize this implementation to fit various app requirements.
Jetpack Compose’s declarative nature allows for endless possibilities in crafting dynamic and user-friendly interfaces. By mastering techniques like this, you can enhance the user experience in your applications while maintaining clean and maintainable code.
Call to Action
If you found this tutorial helpful, consider sharing it with fellow developers! For more tips and in-depth guides on Jetpack Compose and Android development, follow our blog and stay tuned for upcoming posts.
Happy coding!