Annyce Davis

ones and zeros

  • Home
  • Public Speaking
  • About Me
  • Courses
  • Life

Using RxBinding with Kotlin and RxJava2

July 23, 2017 by Annyce Davis 7 Comments

RxBinding provides RxJava binding APIs for Android User Interface (UI) widgets. This allows us to easily translate Android UI events into Observable streams. Let’s look at a simple example of this: we’re going to consider how to execute an asynchronous network request from a Button click event.

build.gradle File

The first thing we need to do is update our application’s build.gradle file. We’re going to add the dependencies needed for RxJava2, RxAndroid, and RxBinding:

dependencies {
    // RxJava
    compile 'io.reactivex.rxjava2:rxjava:latest_version'
    compile 'io.reactivex.rxjava2:rxandroid:latest_version'
    compile 'com.jakewharton.rxbinding2:rxbinding-kotlin:latest_version'
}

Depending on the support libraries that you are using in your application, you will need to include one or more of the following dependencies:

compile '...:rxbinding-support-v4-kotlin:latest_version'
compile '...:rxbinding-appcompat-v7-kotlin:latest_version'
compile '...:rxbinding-recyclerview-v7-kotlin:latest_version'

The full listing is available here.

Sample Application

Our sample application will consist of one Activity, named RxBindingActivity. This contains a Button which when clicked will load a list of users from a remote API into a TextView and then display a Toast.

Sample Application

For our networking layer we’re going to use Retrofit. This will allow us to define our desired /users endpoint with the following:

@GET("/users")
fun getUsers(): Single<List<User>>

Notice how we simply specify our method and its return value. In this a case a Single of type List<User>. We decided to use a Single here as it works best when you don’t expect to receive multiple values. Then in our RxBindingActivity class we can retrieve and log the list of users with the following code:

fun getAllUsers(): Single<List<User>> {
    return api.getUsers()
              .subscribeOn(Schedulers.io())
              .onErrorResumeNext(Single.just(emptyList()))
              .doOnSuccess { Timber.i("users: $it") }
}

We’re also using the onErrorResumeNext operator to emit an empty List in the case where we receive an error from the API.

Handling Click Events

Now that we can retrieve the list of users, we want to connect this to our Button. For that we will use the clicks() Extension method which is available on View elements from the rxbinding-kotlin dependency. First, we get access to our desired view element by means of the lazy delegate available in Kotlin. Then we apply the clicks() method on the Button.

val myButton: Button by lazy { findViewById(R.id.button) as Button }
...
myButton.clicks()

If we take a look at the Extension method from RxView.kt we can see that it returns an Observable<Unit>.  This means that we can then apply any desired RxJava operators as we see fit. It’s also important to note that the created Observable has a strong reference to the View so we need to make sure we clean up after ourselves when we’re done.

RxView.kt Code Snippet

Connecting the newly created Observable to our API request can be done by using the flatMapSingle operator. This will allow us to transform our Observable<Unit> to Single<List<User>>.

FlatMapSingle Operator

So we’ll use the following code to do just that:

myButton.clicks()
        .observeOn(Schedulers.io())
        .flatMapSingle { getAllUsers() }
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
            this::handleUsers,
            this::handleError
        )

Next, to tie it all together we subscribe() to the Single and provide method references to deal with both the success and error cases. That’s all we need to handle as we’re working with a Single. However, we’re not done yet. Recall we mentioned that we need to clean up after ourselves when dealing with the Observable created from the clicks() method. For that we have a few different options. The simplest way to handle it is to store the reference as a Disposable and then call its dispose method when we’re done with the Activity.

var disposable: Disposable? = null

override fun onResume() {
    ...
    disposable = myButton.clicks()
            .observeOn(Schedulers.io())
            .flatMapSingle { getAllUsers() }
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                    this::handleUsers,
                    this::handleError
            )
}
override fun onPause() {
    disposable?.dispose()
    super.onPause()
}

The complete source code for the sample application can be found here. I’d love to see more examples of RxBinding being used with Kotlin. If you know of any, please leave a reference in the comments section. Thanks!

Special thanks to: @PatrickDattilio, @donnfelker, @kaushikgopal and @moyheen for reviewing this post!

Share this:

  • Click to share on Twitter (Opens in new window)
  • Click to share on Facebook (Opens in new window)
  • Click to share on LinkedIn (Opens in new window)

Related

Filed Under: Android, Kotlin, RxJava Tagged With: Kotlin, Retrofit, RxBinding, RxJava2

Follow Me

What engineering leaders need to know from this year’s Google I/O

I didn't intentionally aim to create a rhyming title, but there you have it. Each year, I look forward to Google I/O like a kid going back to school. This year … [Read More...]

Talk: The Real MVP

You have an idea for a new app. You've secured buy-in from the business. What's next? The MVP. But what does it take to ship a new app these days? What are the … [Read More...]

Categories

  • Android (55)
  • Career (2)
  • Communication (4)
  • Flutter (1)
  • Git (4)
  • Gradle (4)
  • Grails (23)
  • Java (8)
  • JavaScript (6)
  • Kotlin (17)
  • Life (4)
  • Public Speaking (23)
  • RxJava (1)
  • Software Development (7)
  • Twitter (3)
  • Uncategorized (11)
  • Video Course (5)

Copyright © 2023 · Beautiful Pro Theme on Genesis Framework · WordPress · Log in

 

Loading Comments...