Article

What if I want to [[ display both the error message ]] and the "eye" icon at the same time?

Topic: TravelBy Rchard MathewPublished Recently added

Legacy signals

Legacy popularity: 222 legacy views

You are working on an Android app with a target SDK of 24 (Android 7.0 Nougat). In this scenario, you're trying to create a user interface with three password fields. These fields have a "show/hide password" icon, which is commonly used for better UX. However, you're facing an issue where the error icon (set using setError("error message")) overlaps with the "eye" icon used for toggling password visibility. You want the error icon to be positioned in a way that it doesn't interfere with the show/hide password icon, and you're also trying to keep the "eye" icon in its current position.

Approach Overview

We'll need to solve this layout issue by either adjusting the positioning of the error icon, modifying the layout of the EditText, or using custom drawable resources for the error icon. Since you're working on a legacy SDK (API level 24), we should be mindful of compatibility and not use Material Design components.

Here’s a step-by-step guide on how to solve this problem.

1. Understanding the Default Layout and the Problem

In Android, the EditText widget can display both the error icon (when setError() is called) and other icons (like the "eye" icon) in its compound drawables.

When you use setError() on an EditText, the error icon is displayed at the end of the EditText, which is typically where the "eye" icon might also be placed. This results in the overlap issue you're seeing, where the error icon obscures the password visibility toggle icon.

The default behavior places the icons in the following manner:

End Drawable (Right side): Error icon when an error is set.

Start Drawable (Left side): "Eye" icon for password visibility.

However, as you noticed, the issue arises when both icons (error and "eye") need to occupy the same space, causing one to overlap the other.

2. Solution: Adjusting the Layout with Custom Error Icon

You have two main options to resolve this issue:

Adjust the positioning of the error icon so that it doesn’t overlap with the "eye" icon.

Use custom drawables for the error icon to better position it.

Let's walk through both solutions.

Solution 1: Use a Custom Drawable for the Error Icon

Instead of using the default error icon, you can create a custom drawable to represent the error icon and position it differently from the "eye" icon. Here's how to approach it:

Step 1: Define the Custom Drawable

You can create a custom drawable that will be used for the error. This drawable can be a simple icon or an image, or you could even design it with some padding to keep it away from the "eye" icon.

For instance, create an XML file in res/drawable named error_icon.xml:

xml

Copy code

<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:left="8dp" android:right="8dp"> <bitmap android:src="@drawable/ic_error" android:gravity="center" /> </item> </layer-list>
This will give your error icon some padding on both sides (left and right) to keep it from interfering with other icons. You can adjust the values of android:left and android:right according to your layout needs.

Step 2: Set the Drawable to the EditText

Once the custom drawable is defined, you can assign it to the EditText by using setCompoundDrawablesWithIntrinsicBounds().

java

Copy code

EditText passwordField = findViewById(R.id.password_field); // Set the error icon with custom padding to ensure it doesn't overlap the "eye" icon passwordField.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.error_icon, 0);
You can call this method after setting the error message:

java

Copy code

passwordField.setError("Error: Invalid password");
This method will ensure the error icon doesn’t overlap with the "eye" icon, as it’s been padded properly with the layer-list.

Solution 2: Modify the EditText Layout to Avoid Overlap

If you'd like to keep the default error icon behavior but want to avoid overlap, you could add padding to the EditText to push the error icon (and the "eye" icon) away from each other.

Step 1: Use Padding to Separate the Icons

You can add padding on the right side of the EditText so that the error icon and "eye" icon have enough space between them.

java

Copy code

EditText passwordField = findViewById(R.id.password_field); passwordField.setPadding(0, 0, 50, 0); // Add right padding to avoid overlap
This adds padding to the right side, giving the icons room to exist separately.

Step 2: Check and Update Visibility Toggle Icon

Once you've set the padding, make sure that the "eye" icon remains in place. If you use setCompoundDrawablesWithIntrinsicBounds() to set the "eye" icon, you can check whether it is aligned properly.

java

Copy code

Drawable eyeIcon = getResources().getDrawable(R.drawable.ic_eye); passwordField.setCompoundDrawablesWithIntrinsicBounds(null, null, eyeIcon, null);
This ensures that the eye icon is positioned correctly, even if the padding is adjusted. You may also want to experiment with padding the EditText dynamically, depending on whether the error is displayed, to avoid unnecessary space when no error is present.

3. Alte
ative Solution: Use a TextInputLayout for Better Control

Although you mentioned you can’t use Material components because your target SDK is 24, it’s worth mentioning that a TextInputLayout is an excellent solution for this problem. This component allows for better handling of errors and icons without worrying about overlap.

If you could switch to using TextInputLayout, you would have automatic handling of error messages and icons, which would solve your issue neatly. Here’s how you can do it:

xml

Copy code

<com.google.android.material.textfield.TextInputLayout android:id="@+id/password_input_layout" android:layout_width="match_parent" android:layout_height="wrap_content" app:endIco
Mode="password_toggle"> <EditText android:id="@+id/password_field" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Password" /> </com.google.android.material.textfield.TextInputLayout>
With TextInputLayout, the error icon and the password visibility toggle ("eye") are managed more effectively, reducing the likelihood of overlapping.

4. FAQ (Frequently Asked Questions)

1. How can I avoid overlap between icons when using setError() in EditText?

The most common solution is to add custom padding to the EditText or use a custom drawable for the error icon to separate it from the visibility toggle icon. You can also use a TextInputLayout (if possible) to handle these interactions more elegantly.

2. Can I use TextInputLayout with SDK 24?

Yes, you can use TextInputLayout even if your target SDK is 24, as it is backward-compatible with previous versions of Android. However, to use it, you’ll need to include the Material Design library in your project’s dependencies.

gradle

Copy code

dependencies { implementation 'com.google.android.material:material:1.4.0' }

3. What if the icons are still not aligned correctly even with padding?

If padding alone doesn't resolve the issue, consider creating custom drawable resources for your icons and applying those to the EditText to ensure proper alignment and spacing. This will give you more control over the positioning of each icon.

4. Can I use android:drawableEnd to manage the icons?

Yes, android:drawableEnd is a good option to position your icons on the right side of the EditText. However, if you have multiple icons (like the "eye" icon and the error icon), you may need to adjust the layout dynamically or use a TextInputLayout for better management of the end drawable.

5. What if I want to display both the error message and the "eye" icon at the same time?

To do this, you’ll need to ensure that the error message and the "eye" icon are not positioned on top of each other. You can either use padding or a custom drawable, or you can try using a TextInputLayout, which automatically handles this layout issue.

6. Can I dynamically remove the error icon when no error is present?

Yes, you can dynamically remove the error icon by calling setError(null) on your EditText when the error condition is cleared. Alte
atively, if using a TextInputLayout, it will automatically remove the error icon when the error is cleared.

Conclusion

To solve the issue of overlapping icons in your password fields, you have multiple options. The most straightforward approach involves adjusting the positioning of the error icon, either through custom drawables or padding. If you’re able to, consider using a TextInputLayout for better management of your icons, as it automates a lot of the layout work and reduces the chances of overlap.

Remember to always test across different screen sizes and Android versions to ensure consistent behavior across your user base.

Advanced Solutions and Considerations

While the basic solutions of adjusting padding and using custom drawables may work, there are several more advanced techniques you can explore to make sure your app’s UI works smoothly and remains maintainable in the long run.

1. Using setCompoundDrawablesWithIntrinsicBounds for Precise Icon Placement

In Android, EditText allows you to set compound drawables that will appear at the start, top, end, or bottom of the text field. By utilizing setCompoundDrawablesWithIntrinsicBounds(), you can control exactly where your icons appear.

Fine-tuning Icon Placement

Let’s say you want to position both the error icon and the “eye” icon at the right edge of the EditText, but avoid them overlapping.

The setCompoundDrawablesWithIntrinsicBounds() method allows you to specify four drawable positions: start (left)

top

end (right)

bottom

For example, you can modify the EditText like this:

java

Copy code

EditText passwordField = findViewById(R.id.password_field); // Define the "eye" icon (for password visibility toggle) Drawable eyeIcon = getResources().getDrawable(R.drawable.ic_eye); Drawable errorIcon = getResources().getDrawable(R.drawable.ic_error); // Set the "eye" icon to the end of the EditText passwordField.setCompoundDrawablesWithIntrinsicBounds(null, null, eyeIcon, null); // Dynamically set the error icon when needed passwordField.setError("Invalid password", errorIcon); // Adjust padding and other layout properties to prevent overlap passwordField.setPadding(0, 0, 50, 0);
In this case:

setCompoundDrawablesWithIntrinsicBounds() positions the "eye" icon at the end (right side).

setError() places the error icon in the same position but does so without messing up the "eye" icon if you control the layout using padding.

2. Layering Icons with LayerDrawable

If you need more control over how icons appear on top of each other or side by side, you can use a LayerDrawable. This allows you to stack multiple drawable resources in a specific order. For example, you could stack the error icon on top of the "eye" icon but control their visibility and padding.

Example of LayerDrawable for Stacked Icons:

xml

Copy code

<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:left="0dp" android:right="24dp"> <bitmap android:src="@drawable/ic_eye" android:gravity="center" /> </item> <item android:left="24dp"> <bitmap android:src="@drawable/ic_error" android:gravity="center" /> </item> </layer-list>
This layout makes the error icon appear with a slight offset from the "eye" icon to prevent overlap. You can load this drawable into your EditText like so:

java

Copy code

Drawable layeredIcon = getResources().getDrawable(R.drawable.layered_error_eye_icon); passwordField.setCompoundDrawablesWithIntrinsicBounds(null, null, layeredIcon, null);
This solution can be beneficial when you need to fine-tune how different icons appear together, ensuring they stay separated and visually balanced.

3. Handling Multiple Errors with Different Icons

If you have multiple error states (e.g., invalid password format, passwords do not match), you may want to show different error icons or messages for each case. For instance, one icon might indicate an invalid format, while another shows that passwords don't match.

In such cases, you can use conditional logic to set different error icons based on the specific error:

Example Code:

java

Copy code

EditText passwordField = findViewById(R.id.password_field); String password = passwordField.getText().toString(); // Check the error condition and set appropriate error icon if (password.length() < 8) { passwordField.setError("Password must be at least 8 characters", getResources().getDrawable(R.drawable.ic_length_error)); } else if (!password.equals(confirmPassword)) { passwordField.setError("Passwords do not match", getResources().getDrawable(R.drawable.ic_match_error)); } else { passwordField.setError(null); // Clear error if valid }
In this example:

The first condition checks if the password is too short and shows a custom error icon.

The second condition checks if the passwords match and displays a different icon for that error.

The last condition clears the error when no issue is detected.

This approach allows you to offer more specific feedback to users while keeping the UI clean and usable.

4. Custom Password Visibility Toggle Icon

For password visibility toggling, rather than relying on the default “eye” icon, you can customize it with your own logic and even add animations. For example, you might want to animate the transition of the "eye" icon when the password is shown or hidden.

Custom Toggle Logic with Animation:

Here’s an example of how you can implement a password visibility toggle with an animated icon change:

java

Copy code

ImageView toggleVisibilityButton = findViewById(R.id.toggle_visibility_button); final EditText passwordField = findViewById(R.id.password_field); toggleVisibilityButton.setO
ClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (passwordField.getTransformatio
Method() instanceof PasswordTransformatio
Method) { passwordField.setTransformatio
Method(HideRetu
sTransformatio
Method.getInstance()); toggleVisibilityButton.setImageResource(R.drawable.ic_eye_open); // Eye open icon } else { passwordField.setTransformatio
Method(PasswordTransformatio
Method.getInstance()); toggleVisibilityButton.setImageResource(R.drawable.ic_eye_closed); // Eye closed icon } } });
In this implementation:

setTransformatio
Method() is used to toggle between hiding and showing the password.

The icon changes dynamically based on whether the password is visible or hidden.

You can customize the eye icons to reflect the toggle state, and animate the transition for a smoother user experience.

5. Supporting Legacy Devices (API 24 and Below)

Since you're targeting SDK 24 (Android 7.0), there are a few things to keep in mind when designing your UI and interacting with various components:

Material Design: Many features in Material Design were introduced in SDK 21 (Lollipop) or later, so you won’t be able to use features like TextInputLayout or Material-style EditText out of the box. If you need to support these, you’ll have to manually include Material components as exte
al libraries.

For example, the TextInputLayout is part of the com.google.android.material library, and to use it on devices with SDK versions below 21, you’ll need to ensure backward compatibility by adding the Material Components library to your build.gradle file:

gradle

Copy code

dependencies { implementation 'com.google.android.material:material:1.4.0' // Add the appropriate version }
If you’re unable to use TextInputLayout, you’ll need to use EditText and rely on custom code to achieve a similar experience.

Compatibility Issues: Some properties or layout techniques may not be available on older Android versions, so be sure to test on a variety of devices, especially if you're supporting older phones (API 24 and lower).

Expanded FAQ Section

7. Can I dynamically show or hide the error icon based on validation?

Yes, you can hide or show the error icon dynamically. The setError() method shows an error icon when an error message is passed, and it clears the error when setError(null) is called. To hide or remove the error message, just clear the error:

java

Copy code

passwordField.setError(null); // Hides the error icon and message
Alte
atively, if you're using a custom drawable for the error icon, you can replace it with another drawable or use setCompoundDrawablesWithIntrinsicBounds() to remove the icon altogether.

8. What if I want to align my icons in a specific way (centered, right-aligned, etc.)?

The default placement of icons in EditText fields is typically left or right aligned, depending on whether you use android:drawableLeft or android:drawableRight. However, you can align them more precisely using setCompoundDrawablesWithIntrinsicBounds() or by adjusting layout properties.

To center the "eye" icon:

java

Copy code

passwordField.setCompoundDrawablesWithIntrinsicBounds(null, null, getResources().getDrawable(R.drawable.ic_eye), null);
You can also manually adjust the padding to achieve your desired alignment.

9. How do I handle the password input field when a user taps outside the field?

If a user taps outside the EditText field and you want to hide the error or the password visibility toggle, you can add a touch listener to clear the error or reset the state.

For example:

java

Copy code

passwordField.setO
FocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (!hasFocus) { passwordField.setError(null); // Clear error when focus is lost } } });

10. Is it possible to programmatically set the error icon in a custom location?

Yes, you can manually set the error icon to any drawable you choose, and position it using setCompoundDrawablesWithIntrinsicBounds() as demonstrated earlier. This allows you to programmatically manage multiple error conditions without relying on the default setError() behavior.

Conclusion

This problem of overlapping icons is a common issue in Android development, especially when working with legacy SDKs like API 24. By employing strategies such as customizing drawables, adjusting paddings, and using layer drawables, you can effectively manage the layout of your EditText components and make sure the "eye" icon and error icons don't interfere with each other.

Additionally, as you expand your app’s functionality and handle more complex scenarios (like multiple errors or custom animations for the password visibility toggle), keep in mind that keeping the UI consistent, intuitive, and user-friendly is key to delivering a smooth experience.

By following the guidelines and solutions outlined here, you should be able to maintain good UI practices, even while supporting older Android versions.

Article author

About the Author

Rchard Mathew is a passionate writer, blogger, and editor with 36+ years of experience in writing. He can usually be found reading a book, and that book will more likely than not be non-fictional.

Further reading

Further Reading

4 total

Article

Pattaya, Thailand is known for its sapphire beaches, crazy nightlife and vibrant culture. While it might take a week or longer to soak up the Thai atmosphere, you can make a short trip to enjoy the coastal city of Thailand. This blog will share how you can make it “around Pattaya all-inclusive holidays in 2 days”. So, let’s begin the new adventure. Explore Pattaya in 2 DAYS Here are some of the places that you visit during your short trip to Pattaya. Begin at Central Pa

December 13, 2024

Article

Umrah is no small blessing for pilgrims, as it cleanses their souls of past sins and renews faith in Allah. While it is not compulsory to perform, the holy cities of Mecca and Medina are full of pilgrims for most of the year. This is why different agencies and sometimes airlines offer special travel packages designed specifically for Umrah. These deals cover everything from flights to hotel stays. For those who are planning their first pilgrimage, it can be a bit difficult an

September 23, 2024

Article

Are you dreaming of luxury holidays but need help figuring out where to start? Look no further! This blog will take you through finding the perfect yacht for your luxury holiday , from research to booking. Along the way, you'll be inspired by popular luxury holiday itineraries and find the ideal yacht. So whether you're looking for a relaxing getaway or a thrilling sailing adventure, this blog has everything you need to make it happen! Access the world's superyachts Charterin

March 5, 2024

Article

A yacht is a kind of boat that offers different services to make your vacations enjoyable. Yacht let you sail across different sea areas and spend time while staying in comfort. The yacht is a fully furnished cruise that contains different departments where you can spend time. It lets you sit in the finest comfort and takes you through different locations. A yacht can be the best way to spend holidays because of different services. There are different areas where you can crui

February 12, 2024