using rxjava to solve real world problems

Kotlin Reactive Programming for an Android Sign-Up Screen

RxJava 2.0 is a popular reactive programming library that’s helped countless Android developers create highly responsive apps, using less code and less complexity, especially when it comes to managing multiple threads.

If you’re one of the many developers who’s made the switch to Kotlin, then it doesn’t mean you need to give up on RxJava! 

In the first part of this series, I showed you how to move from programming with RxJava 2.0 in Java, to programming with RxJava in Kotlin. We also looked at how to banish boilerplate from your projects, by taking advantage of RxKotlin’s extension functions, and the secret to dodging the SAM conversion problem that many developers encounter when they first start using RxJava 2.0 with Kotlin. 

In this second instalment, we’ll be concentrating on how RxJava can help solve the issues you’ll encounter in real-life Android projects, by creating a reactive Android application using RxJava 2.0, RxAndroid and RxBinding.

How Can I Use RxJava in Real-World Projects?

In our Reactive Programming with RxJava and RxKotlin article, we created some simple Observables and Observers that print data to Android Studio’s Logcat – but this isn’t how you’ll use RxJava in the real world.

In this article I’m going to show you how to use RxJava to create a screen that’s used in countless Android applications: the classic Sign Up screen. 

A typical Sign Up screen that youll find in countless Android applications

If your app has any kind of Sign Up experience, then it’ll typically have strict rules about the kind of information it accepts. For example, maybe the password needs to exceed a certain number of characters, or the email address must be in a valid email format.

While you could check the user’s input once they hit the Sign Up button, this isn’t the best user experience, as it leaves them open to submitting information that’s clearly never going to be accepted by your application.

It’s far better to monitor the user as they’re typing, and then give them a heads-up as soon as it becomes clear they’re entering information that doesn’t meet your app’s requirements. By providing this kind of live and ongoing feedback, you give the user the opportunity to correct their mistakes before hitting that Sign Up button.

While you could monitor user activity using vanilla Kotlin, we can deliver this functionality using much less code, by enlisting the help of RxJava, plus a few other related libraries.

Creating the User Interface

Let’s start by building our user interface. I’m going to add the following:

  • Two EditTexts, where the user can enter their email address (enterEmail) and password (enterPassword).
  • Two TextInputLayout wrappers, which will surround our enterEmail and enterPassword EditTexts. These wrappers will display a warning whenever the user enters an email address or password that doesn’t meet our app’s requirements.
  • A password visibility button, which allows the user to toggle between masking the password and viewing it as plain text.
  • Sign up button. To help keep this example focused on RxJava, I won’t be implementing this part of the sign up experience, so I’ll be marking this button as disabled.

Here’s my finished layout:

You can copy/paste this into your app if you want, or you can just download the project source code from our GitHub repo.

Creating a Reactive Sign-in Experience With Kotlin

Now let’s look at how we can use RxJava, plus a few related libraries, to monitor user input and provide feedback in real time. 

I’ll be tackling the Sign Up screen in two parts. In the first section, I’ll show you how to use the RxBinding library to register and respond to text change events. In the second section, we’ll create some transformation functions that validate the user’s input, and then display an error message where appropriate.

Create a new project with the settings of your choice, but when prompted make sure you select the Include Kotlin Support checkbox. 

Responding to Text Change Events

In this section, we’ll implement the following functionality: 

  • Detect when the user is typing in the enterEmail field.
  • Ignore all text change events that occur within a short space of time, as this indicates that the user is still typing. 
  • Perform an action when the user stops typing. In our finished app, this is where we’ll validate the user’s input, but in this section I’ll just be displaying a Toast

1. RxBinding 

RxBinding is a library that makes it easier to convert a wide range of UI events into Observables, at which point you can treat them just like any other RxJava data stream.

We’re going to monitor text change events, by combining RxBinding’s widget.RxTextView with the afterTextChangeEvents method, for example:

The problem with treating text change events as data streams, is that initially both the enterEmail and enterPassword EditTexts will be empty, and we don’t want our app to react to this empty state as though it’s the first data emission in the stream. RxBinding solves this problem by providing a skipInitialValue() method, which we’ll use to instruct each Observer to ignore their stream’s initial value.

I look at the RxBinding library in greater detail in my RxJava 2 for Android Apps article.

2. RxJava’s .debounce() Operator

To deliver the best user experience, we need to display any relevant password or email warnings after the user has finished typing, but before they hit the Sign Up button.

Without RxJava, identifying this narrow window of time would typically require us to implement a Timer, but in RxJava we just need to apply the debounce() operator to our data stream.

I’m going to use the debounce() operator to filter out all text change events that happen in quick succession, i.e. when the user is still typing. Here, we’re ignoring all text change events that happen within the same 400 milliseconds window:

3. RxAndroid’s AndroidSchedulers.mainThread()

The RxAndroid library’s AndroidSchedulers.mainThread gives us an easy way to switch to Android’s all-important main UI thread.

Since it’s only possible to update Android’s UI from the main UI thread, we need to make sure we’re in this thread before we attempt to display any email or password warnings, and before we display our Toast

4. Subscribe

To receive the data being emitted by enterEmail, we need to subscribe to it:

5. Display the Toast

Eventually, we want our application to respond to text change events by validating the user’s input, but to help keep things straightforward, at this point I’m simply going to display a Toast

Your code should look something like this:

6. Update Your Dependencies

Since we’re using a few different libraries, we need to open our project’s build.gradle file and add RxJava, RxBinding and RxAndroid as project dependencies: 

You can test this part of your project, by installing it on your physical Android smartphone or tablet, or Android Virtual Device (AVD). Select the enterEmail EditText and start typing; a Toast should appear when you stop typing. 

Test your projects enterEmail EditText

Validating the User’s Input With Transformation Functions

Next, we need to lay down some ground rules about the kind of input our application will accept, then check the user’s input against this criteria and display an error message where appropriate. 

Checking the user’s email or password is a multi-step process, so to make our code easier to read, I’m going to combine all of these steps into their own transformation function. 

Here’s the start of the validateEmail transformation function:

In the above code, we’re using the filter() operator to filter the Observable’s output based on whether it matches Android’s Patterns.EMAIL_ADDRESS pattern.

In the next part of the transformation function, we need to specify what happens if the input doesn’t match the EMAIL_ADDRESS pattern. By default, every unrecoverable error will trigger a call to onError(), which terminates the data stream. Instead of ending the stream, we want our application to display an error message, so I’m going to use onErrorResumeNext, which instructs the Observable to respond to an error by passing control to a new Observable, rather than invoking onError(). This allows us to display our custom error message.

The final step, is to apply this transformation function to the email data stream, using the .compose() operator. At this point, your MainActivity.kt should look something like this: 

Install this project on your Android device or AVD, and you’ll find that the email portion of the Sign Up screen is now checking your input successfully. Try entering anything other than an email address, and the app will warn you that this isn’t a valid input. 

Enter anything other than a valid email address and the app will display a warning message

Rinse and Repeat: Checking the User’s Password

At this point, we have a fully-functioning enterEmail field – and implementing enterPassword is mostly just a case of repeating the same steps.

In fact, the only major difference is that our validatePassword transformation function needs to check for different criteria. I’m going to specify that the user’s password input must be at least 7 characters long: 

After repeating all of the previous steps, the completed MainActivity.kt should look something like this: 

Install this project on your Android device or AVD, and experiment with typing into the enterEmail and enterPassword fields. If you enter a value that doesn’t meet the app’s requirements, then it’ll display the corresponding warning message, without you having to tap the Sign Up button.

You can download this complete project from GitHub.

Conclusion

In this article, we looked at how RxJava can help solve the real-world problems you’ll encounter when developing your own Android applications, by using RxJava 2.0, RxBinding and RxAndroid to create a Sign Up screen. 

For more background information about the RxJava library, be sure to check out our Get Started With RxJava 2.0 article. 

Powered by WPeMatico

Leave a Comment

Scroll to Top