Accessible Text Input in Android

By Chris McMeeking August 12, 2015
View non-AMP version at deque.com

Deque U Best Practices Logo
This post was co-authored by Chris McMeeking and Melinda Kothbauer.

The default text entry field in Android is the EditText object. EditText objects are difficult because the common practices for making Android UI elements accessible (content descriptions), do not work. Android provides the framework to make EditText objects accessible, but it is important to know what, when, and how to use the built-in tools. In this post we will discuss:

  • Difficulties unique to EditText objects
  • How to make EditText objects accessible
  • An in depth discussion of an example found within our open source Android app
  • Best Practices regarding EditText objects

Why are EditText objects difficult?

In order for both sighted and non-sighted users to use EditText objects effectively, they need to know what information the EditText requires. Without some sort of association to the required information, no one can accurately input the information that developers intended to go in the EditText object.

Developers commonly use hints to provide this information to users. However, hints are not consistently accessible. With the huge variety of Android devices and TalkBack versions, hints are announced improperly more often than not. The main problem with hints is that they disappear when a user enters text. This is unhelpful for sighted users, as they can no longer see which information goes into which EditText object, but even worse for non-sighted users. Once text is entered, TalkBack will no longer announce the hint, and instead announces the entered text. Therefore, placing important contextual information within the hint is an Accessibility violation. NOTE: This is version dependent, for example Nexus 6 with Android 5.2+ exhibits this behavior, but Samsung Galaxy 4, with Android 4.4 does not.

Other methods, such as visible labels beside the corresponding EditText object, are improvements over hints. Nevertheless, they still lack proper accessibility mark-up since TalkBack does not automatically associate the visible label with the EditText object. A TalkBack user scrolling through views does not know which label goes with which EditText object.

How to make EditText objects accessible

Making EditText objects accessible is not difficult. All that is required is a visible label beside the corresponding EditText object that is properly associated with its EditText object via the labelFor attribute either placed in xml layout or programmatically.

XML

In XML, adding an association for an EditText object is simple. All you need to do is add a unique id attribute (line 8 below) for the desired EditText object and a labelFor attribute (line 4 below) to the associated TextView object.

[code language=”xml”]
<TextView
android:labelFor=”@+id/edit_text”
android:text=”@string/aac_edit_text_about_label” />

<EditText android:id=”@+id/edit_text”/>
[/code]

Programmatically

It is also possible to create the labelFor association programmatically using one of the two following functions:

setLabelFor(View labeled) or setLabeledBy(View label).

For example,

[code language=”java”]
View view = inflater.inflate(R.layout.fragment_edit_text_fixed, container, false);
TextView textView = (TextView) view.findViewById(R.id.aac_edit_text_fixed_heading_1);
EditText editText = (EditText) view.findViewById(R.id.aac_edit_text_fixed_edit_text_1);
textView.setLabelFor(editText);
[/code]

These functions are relatively self-explanatory; simply send the appropriate view (the EditText if using setLabelFor or the TextView if using setLabeledBy). These functions are especially useful when creating dynamic lists or views programmatically rather than a pre-defined xml layout.

EditText Example

This discussion references our open source Android app. Please get this running on your device and turn TalkBack on. Before continuing find the “Edit Texts” story, located in the main menu, and navigate to the broken tab. The following discussion will refer to the broken tab view as well as the fixed tab view.

No Accessibility Markup – A11y Violation

On the broken tab, you will see two examples of how NOT to code with EditText objects. In the first example, it is clear to a sighted user what information belongs in which EditText. That being said, if you turn on the TalkBack simulation (by clicking the eye icon in the upper right hand corner) and scroll through these views, it is unclear which label is associated with which EditText object.

Using Placeholder Text – A11y and Usability Violation

In the second example, it is again clear to a sighted user where to type in what – at first. These EditText objects appear to have hints, but the text is actually just hardcoded text that will never repopulate the field once edited (try it!) as hints do sometimes, depending on the Android version, device, etc. It is clear that this method is ineffective for both sighted and non-sighted users.

Using labelFor Attribute – A11y Best Practice

Now navigate to the fixed tab. At first glance, the two examples look nearly identical to the broken ones – it is important to remember that adding accessibility features will not change your layout much! The difference here lies in the code. The top example with visible labels are all correctly associated with their corresponding EditText objects using the xml labelFor attribute. Now when you scroll through the views using TalkBack, the label is announced with the EditText object’s information, removing all ambiguity.

Using Hints – WARNING!

The second example on the fixed tab is particularly interesting. It uses hints to convey all information about what belongs in the EditText object. This is a commonly accepted way to mark up EditTexts both for usability and accessibility; however, neither of those goals are accomplished consistently using hints. Depending on your device, Android version, TalkBack version, etc. you may get different TalkBack announcements when scrolling through these EditText objects. Try it before editing them, while editing, and after removing all changes to see the differences. From a pure usability standpoint, if you are asked to enter some piece of information (for example, a first name), and you begin to enter your information, the hints will disappear. The helpful information is now gone and you have no way to ensure you entered the correct information in the correct EditText object. What if it was actually asking for the last name first? You have no way to double check.

Best Practice

Hints are commonly used as accessibility markup; however, they are often misused in this way. Hints should not contain critical contextual information. This information should go into a visible label that is appropriately associated with the EditText object using the labelFor attribute. Hints can then be used to help clarify required information, for instance when a specific format is desired (such as a phone number or date) or to give an example of information that can go in the EditText object. In such instances, they should likely be accompanied by form validation techniques (blog post coming soon), to ensure the formatting requirements are enforced in an accessible way. The important take away is that hints containing important contextual information are almost always an accessibility violation.

Tips

  • Do not use hints for critical contextual information, only use for secondary information (like sample input data).
  • Use the programmatic approach for dynamic views such as ListViews, Menus, etc.
  • Always have a visible label that is associated via a labelFor attribute to its EditText object

We hope you found this tutorial useful.

Learn more…