Android: Reactive View Part II
Overview
This is the 2nd post of the 3 part blog posts:
- Android: Reactive View Part I
- Android: Reactive View Part II ← This Post Is Here!
- Android: Reactive View Part III.
A simple example is compared between reactive and non-reactive view layer in the previous post. In this post, let's look at a more complex example.
1. Reddit Example
Let's say we are building this:

Description
- when we click
Load More, more posts will be loaded - when
Load Moreis clicked again, the next page will be loaded - when
Refreshis clicked, all current posts will be erased, and latest posts will be re-fetched - when
Change Subredditis clicked, all current posts will be erased, different posts will be fetched from another subreddit endpoint. (for people whose not familiar, subreddit is like a sub-topic in Reddit)
2. MVVM + Non-Reactive Views
This is the code for the Activity and ViewModel using the Non-Reactive View approach.
fun onCreate() {
rxViewLoadMoreButton.setOnClickListener {
viewModel.onLoadMoreClick()
}
rxViewRefreshButton.setOnClickListener {
viewModel.refreshClick()
}
rxViewChangeSubredditButton.setOnClickListener {
viewModel.randomSubredditClick()
}
}
fun onLoadMoreClick() {
loadMorePosts()
}
fun refreshClick() {
redditApi = RedditApi(redditApi.subreddit)
loadMorePosts()
}
fun randomSubredditClick() {
redditApi = RedditApi(RedditApi.getRandomSubreddit())
loadMorePosts()
}
fun loadMorePosts() {
redditApi.getMorePosts()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ newPosts ->
screenState.postValue(newPosts)
}, {
it.printStackTrace()
})
.addTo(disposables)
}
Similar to previous example, you will notice that in every button.onClickListener(), you will always see viewModel.somethingClick(). If you look inside the ViewModel, you will see the all of 3 of the methods: refreshClick(), randomSubredditClick() and onLoadMoreClick() , ultimately lead to calling loadMorePosts().
💡 This can all be merged together when the view layer is reactive. 💡

The full code can be found here:
Feel free to download the repo and take a closer look in Android Studio!
3. MVVM + Reactive Views
Let's check the implementation of Reactive Views.
val viewInput: RxReactiveViewsViewModel.ViewInput = object : SomeViewModel.ViewInput {
override val loadMoreClickObservable by lazy {
rxViewLoadMoreButton.clicks()
}
override val refreshClickObservable by lazy {
rxViewRefreshButton.clicks()
}
override val randomClickObservable by lazy {
rxViewChangeSubredditButton.clicks()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_reactive_views)
rxViewRecyclerView.adapter = adapter
val viewModel = ViewModelProviders.of(this, SomeViewModel(viewInput)).get(SomeViewModel::class.java)
lifecycle.addObserver(viewModel)
viewModel.screenState.observe(this, Observer { list ->
adapter.submitList(list)
})
}
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreate() {
viewInput.apply {
Observable.merge(
loadMoreClickObservable,
refreshClickObservable.doOnNext { redditApi = RedditApi(redditApi.subreddit) },
randomClickObservable.doOnNext { redditApi = RedditApi(RedditApi.getRandomSubreddit()) }
)
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(Schedulers.io())
.flatMap { redditApi.getMorePosts() }
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ newPosts ->
screenState.postValue(newPosts)
}
}, {
it.printStackTrace()
})
.addTo(disposables)
}
}
Now all the view clicks, are made reactive by calling button.clicks() method from RxBinding library. They are passed into the ViewModel as Observables. Now it's up to the ViewModel to decide how to connect them together.
Over here, Observable.merge() is a suitable operator to do combine all the events together.

You can see from the diagram that all the streams are connected and merge() into a single stream which ultimately calls redditApi.getMorePosts().
Take note of:
- how
refreshClickObservableis usingdoOnNext()to refresh theredditApi - how
randomClickObservableis usingdoOnNext()to randomize theredditApi - then both of them get merged into the same stream
Working Code
The working code is available at Github in as a Pull Request. By using a pull request format, you can see the exact diff of the files for making the views Reactive. Feel free to clone a copy and view in Android Studio.
Discussion
Now let's take a closer look at each of the diagrams.
| Non-Reactive View | Reactive View |
|---|---|
![]() |
![]() |
You can see that the non-reactive logic is doing a little bit of ping-ponging, where the activity has to call the onClick() counterpart in the viewModel methods. Besides, all the 3 methods inside the viewModel has to call loadMore() for 3 times.
In the reactive-view code, everything is interconnected together. 3 streams of clicks are all merged() together into an ultimate stream.
It's arguable that which one is more readable by looking at the diff in the Pull Request. I think it really depends on one's familiarity of RxJava's syntax. However, if we only look at the image diagrams, it's clear that the reactive-view version is cleaner and more streamlined.
I noticed that the more I got familiarized with RxJava's syntax, the more I prefer to make the view layer reactive. Also, as the situation become more complex, reactive code will become easier to read than non-reactive code implementing the same thing.
4. A More Complete Example
The example used in this post is not yet the real production code, because the Load More is triggered by a button instead of being triggered by reaching the bottom of the list. Internet connection is not checked. Refresh is done by a button instead of Pull-to-Refresh. Among other stuff...
If you're interested in a more complex example, feel free to check out this repo (github.com/worker8/Pixels) I made. It's a continuation of this post with all the drawbacks addressed and views being reactive.
Here's a screenshot of the app:

Here's the link to the viewModel: https://github.com/worker8/Pixels/blob/master/app/src/main/java/beepbeep/pixelsforredditx/home/HomeViewModel.kt
5. Closing.. 🚪
It's a debatable topic which approach is better. There is certainly no one single way to write software. If you haven't try this Rx-View approach yet, I hope you would try out after reading this post.
If you're still not convinced about making the view reactive, perhaps I didn't do a good job in the post, or perhaps this approach doesn't suit your taste.
Anyhow, I hope you still learn something! 😄
Tan Jun Rong
Clap to support the author, help others find it, and make your opinion count.