Android SearchView-Using RxJava
Ever noticed that as we start typing some characters in SearchBar we see a list of results automatically and it updates as you type. Nowadays almost all the applications that we use every day have this feature to search so that you can get the result as per your need without scrolling too much.
Now there’s more than one to implment the same functionality but one of the best one I came across was by using Rxjava operators. We’ll go through how java operators saved soo much of my time by implementing features that I never thought would be possible so easily.
There are a number of features that one would want to have when implementing SearchView such as
- Search only when text length is more than 3 character
- Convert all character to lowercase
- Search only when the user stops typing. This will not only decrease the number of API calls drastically but will also provide better feedback to the user
- Cancel fetching results from the network if the user has changed the query
All of these are possible by using operators which we will go through shortly.
Include RxJava dependencies
The first step would be to mention libraries so that your project supports RxJava. Add the following lines in app-level Gradle file
Convert SearchView into Observable
We can make SearchView Observable by using the PublishSubject. We are using here SearchView but one can also use EditText. In the case of EditText, you’ll have to use text change listener instead of query text listener.
Once we have made SearchView observable we can apply all the operators as per our requirement as shown below.
Let's go through each one the operators one by one-
The debounce operator is used to detect a delay when the user stops typing and requests data from API. For instance, the user is searching for “cat” and the user types “c, “ca”, “cat” and so on, in a very short time. So there will be too many network calls every time the user types something. But the user is finally interested in the result of the search “cat”. Ideally, there should be no network calls for “c” and “ca” as the user typed those in a very short time. So denounce will for the given time and will ignore query if the user types something in between and will only execute query when the user stops typing
- SwitchMap: The switchMap operator is used to avoid the network call results which are not needed more for displaying to the user. Let say the last search query was “cat” and there is an ongoing network call for “ab” and the user typed “cat”. Then you are no more interested in the result of “ca”. You are only interested in the result of “cat”. So, the switchMap comes to the rescue. It only provides the result for the last search query(most recent) and ignores the rest.
- Filter: One would not like to search for an empty string or when a string is too small to produce a desirable result. Filters operator helps to filter these kind of unwanted strings and thus helps in saving network calls
- DistinctUntilChanged: The distinctUntilChanged operator is used to avoid duplicate network calls. Let say the last on-going search query was “cat” and the user deleted “t” and again typed “t”. So again it’s “cat”. So if the network call is already going on with the search query “cat”, it will not make the duplicate call again with the search query “cat”. So, distinctUntilChanged removes duplicate consecutive items emitted by the source Observable.
If your project does not have API retrofit calls implemented with RxJava then you won't be able to do much to stop duplicate API calls. I have found a way around this where one will cancel the API call if it's still in progress and then only make a new call.
That’s it for now!!
Thanks for reading and don’t forget to share it with your fellow developers :)
This post was originally posted on CodeTheraphy