A Holistic Approach to Handling User Input in Android

Chukwuemeka Nwagu
ProAndroidDev
Published in
5 min readFeb 4, 2021

--

Collecting input from users is an important part of many android applications. From simple login forms to forms as complex as creating a new entry in a contacts app, how do developers handle user input complexities (getting input in a stream, validating input, displaying validation error or other feedback like password strength, managing lifecycle state, etc) in their applications? There are quite a few moving parts involved.

In this article, we will highlight and discuss in some detail three qualities that are important for any program that handles user input. I will also introduce a general architecture that can be used to organize forms in a structured way, easier to manage.

1. Holistic

This means that the program for handling user input sees all the input fields in a screen as part of the same ‘form’ while the individual input fields are form fields. (Compare user input in apps with paper forms that might contain fields for input like names, checkboxes for gender or marital status, a space to affix a passport, and perhaps a space to sign your signature or impress your thumbprint.) Just like paper forms, a program to collect input can be organized in the same way into forms, and each form must be able to collect a variety of input types (both generic and custom types).

This form must also have the capability to be validated with a single method call. This means having a structure like this:

2. Reactive

This style of programming needs little introduction. In our case, it implies observing user input in continuous streams. Rx is implemented in most Android apps today using the RxBinding library. This library is an extension of the popular RxJava library. It allows developers to handle interaction with UI elements in a reactive manner. It also allows two-way communication between view models and UI. However, this library is not lifecycle-aware out of the box. Because of this and some other advantages, the Android LiveData library stands as the best kind of observable to use between UI and view model (which is where our form objects should be found).

Assuming an MVVM architecture, data from the user flow from UI to ViewModel, while feedback after validation flow in the opposite direction. There might be other metadata that might also be passed either way, such as user behavior or triggers that bring a particular input field to focus.

The mainstream two-way flow of data between the views and the ViewModel can best be handled by coupling Android data binding with LiveData. However, it is necessary for each form field to have observable parameters to handle all the other important metadata.

loginViewModel.username.error.observe(lifecycleOwner, {
binding
.usernameEdit.error = it
})
loginViewModel.username.requestFocus.observe(lifecycleOwner, {
// bring view to focus
})

In addition to being able to observe each of the fields that make up a form, the entire form should also be observable for completeness. This makes it possible to, for instance, activate a submit button when the form is okay for submission and deactivate it otherwise.

Codewise, this will look something like this:

loginViewModel.loginForm.isComplete.observe(viewLifecycleOwner, Observer {
binding
.btnLogin.isActivated = it
}
)

3. Auto-validating

These days, almost all applications apply inline auto-validation in their forms. It is never great UX to wait until a user has finished filling a form and clicked on submit before all the input is validated. However, even while implementing auto-validation, there is still some gray area around when to show the feedback from this validation.

Imagine a user trying to enter her phone number in an application; she keys in the first digit and immediately sees a red warning below the box saying “Invalid phone number!”. On a bad day, she might feel like Of course, I know that, stupid! It is a subtle, nagging thing, but it also signifies bad UX.

While researching auto-validation and the best time to display validation messages, I came across this old article that describes best practices for validating web forms. The same principles could apply to Android as well.

The article makes a distinction between showing inline validation ‘on blur’ (when the field loses focus) versus ‘on keypress’. Apparently, showing validation on keypress ‘made the most sense for questions with strict boundaries’ such as required formatting for a new user password.

I came to the conclusion that there are three possible types of feedback after input validation:

  1. Helpful feedback on the input (such as the strength of a new password)
  2. Error messages (such as “ZIP code must be a 6 digit number”, or “Field cannot be empty”)
  3. A success message

Helpful feedback is best displayed progressively as the user types. However, error messages must begin to be shown only when the UI box for the field loses focus, indicating that the user is done inputting. Done this way, users tend to complete forms more quickly and with higher satisfaction ratings. And of course, a field that has been successfully completed is either left without error messages or with some appropriate indicator (green tick perhaps) that signifies it is validated.

I have encapsulated these three qualities into a simple open-source library for managing forms in Android applications. The code samples in this article show the library in action.

Did you find this helpful? Let me know what you think in the comments!

--

--