Building an AutoCompleting EditText using RxJava

Craig Russell
ProAndroidDev
Published in
3 min readJan 18, 2018

RxJava can simplify the fairly complex interactions needed to build an autocompleting EditText view in Android.

Examples of this interaction are commonplace; open your favourite browser on your phone and start typing in the search bar. You’ll likely see results automatically flash up as you type.

While a common enough feature, there are many suggested implementations on how this can be built, and there are many nuances to the problem. Here is one approach that seems to be working well.

I decided to use RxJava as the crucial ingredient, and a regular old EditText and RecyclerView to accept the input and display the results respectively.

The End Result

For a full working example, you’d best check out the source code for DuckDuckGo Android on GitHub.

The final result makes use of the following RxJava concepts:

Activity

The Activity is fairly light on code, as it should be. We add a TextWatcher and pass through the new query to the ViewModel on every change.

ViewModel

The ViewModel has all the good bits!

AutoCompleteApi

This requires your implementation: from a query, you need to return an Observable of autocomplete suggestions.

fun autoComplete(query: String): Observable<AutoCompleteResult>

You might obtain this from querying your DB. Or you might do as I do here in this project and make an HTTP request, using Retrofit to return your result as an Observable.

Breaking it Down

The two main parts that fit together to make this work:

  • Limiting number of requests being made
  • Canceling requests that are no longer useful

Limiting Number of Requests

Naive Approach (don’t do this)

A naive approach would be to fire an API call with every character change in the EditText. However, the likelihood is that the users can type quickly enough that you can greatly reduce the number of API calls made by not searching while they are still adding more characters.

If the user is going to search for RxJava there is little point in fetching autocomplete suggestions for R when tens of milliseconds later, the user has typed more characters. Having API requests in flight simultaneously for R, Rx, RxJ, RxJa and RxJav will all contribute to slowing down showing the user the results they actually want to see.

Debouncing Requests (do this!)

We can make use of the RxJava debounce() operator to delay taking any action until the user pauses briefly. So while the user continues to type letters, we wait. When the user has stopped typing for a long enough period of time, we then start the API request.

.debounce(300, TimeUnit.MILLISECONDS)
.distinctUntilChanged()

You might decide to adjust the debounce period, but 300ms feels about right to me.

Use of distinctUntilChanged() ensures that the user can search for the same thing twice, but not immediately back to back. There’s no point in cancelling a request to immediately start the same new request when we expect the results to be identical.

http://reactivex.io/documentation/operators/distinct.html

Canceling Previous Requests

The debouncing helps reduce the number of useless requests being made, but if the user pauses long enough for a request to start but then types again, we now have a request in flight which is ultimately pointless; by the time the result arrives back, the user isn’t interested in seeing it any longer as they’ve changed the query already.

By using a switch map, we can cancel a request which is no longer useful to us and start a request for the latest query instead.

The greatest feature of a switch map is its cancelling ability. When there is a new value received, it will unsubscribe from the existing subscription and create a new subscription for the new value.

In other words, when a new query is entered, we discard the existing autocomplete request (if there is one) and create a new autocomplete request.

Demo

DuckDuckGo Android’s autocomplete search results

Published in ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Written by Craig Russell

I make apps; mostly Android. I like equality. Anything techy fascinates me. Android developer.

Responses (6)

What are your thoughts?