Working on the Firefox for Android requestAutocomplete implementation, we’ve been brainstorming some ways to make the upcoming autofill UI pleasant to use. An early prototype of the payment edit dialog:

Empty EditText payment dialog
Payment dialog with empty EditText fields.

This seems innocuous enough — just a few standard EditTexts ready to be joyously filled in by the user. But here’s what that form looks like after it has been filled out:

Filled EditText payment dialog (before)
Payment dialog filled in, using standard EditText fields.

Notice how all of the hints have been replaced by our entered text. We’ve lost all the context of what we’re entering, and we’re left figuring out what the fields represent based on what we entered (the bottom row is particularly cryptic). I’d like to take this opportunity to re-emphasize that this is a an early prototype; the astute reader might point out that we could use better visual cues to indicate what these fields are. For instance, we might show a “/” between the the month and year to indicate a date, and we might put the CVC number directly next to the credit card number to more clearly relate the two fields. These layout flaws notwithstanding, the user is still required to make assumptions about the meaning of each field based on the layout and entered data.

Since most (hopefully, all) of our users have a memory span greater than one second, it may not even seem like an issue that the hints disappear — we probably won’t forget what we’re typing as we’re typing it. But these fields are stored for use later, meaning that if we try to edit this data in the future, we’ll jump right back to the screen above, and we won’t get to see those helpful hints. The only way to show a hint for a given field would be to erase the contents of that field, and that’s obviously a terrible user experience.

To fix this problem, we decided to go with a recently trending pattern: float labels. The concept, introduced by Matt Smith, uses the simple solution of “floating” the labels above the text to prevent the hint from simply disappearing. Here’s our same filled-out form using floating labels:

Filled EditText payment dialog (after)
Payment dialog filled in, using FloatingHintEditText fields.

Much better. The hints are always visible, so if we return to this same dialog in the future to edit our payment information, we don’t lose context about the fields we’re entering.

This custom View — FloatingHintEditText — is implemented as a subclass of EditText. By hooking into onDraw to get the canvas, we can paint our floating hint directly onto the EditText. To transition from the normal hint to the floating one, this implementation linearly interpolates the size/position for each draw frame to create an animation, calling invalidate() to immediately trigger each step.

The code is available on GitHub; at under 150 lines, the implementation is fairly straightforward. You can also check out the screencast demo.

Some limitations:

  • RTL layouts are not yet supported, nor are non-left gravities (center, end, etc.)
  • Due to the position-based transition animation, certain EditText hint layouts can make the animation look less fluid. For instance, multi-line hints or ellipsized hints won’t be as seamless.
  • When the floating hint is visible, the normal hint is hidden using a transparent hint color. Because EditText’s setHintTextColor() is final (why, Android?!), the hint color cannot be changed with this approach as this would not have the desired effect — rather than changing the color of the floating hint, it would make the normal hint reappear.

Enjoy!

FloatingHintEditText: An Android floating label implementation
Tagged on:         

2 thoughts on “FloatingHintEditText: An Android floating label implementation

Leave a Reply

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