(Link to previous article if curious)
I saw this issue regarding Realm and Data Binding a while ago which I felt was never answered. With that in mind, I also felt like I should resolve this issue once and for all and see how data-binding can work with RealmObjects.
You might not know, but a class that defines the Realm schema must either implement RealmModel and have @RealmClass annotation, or extend RealmObject.
This also means you can’t extend BaseObservable easily, because it has a transient field, and transient fields are not supported.
Surprisingly enough, you can’t extend a class that extends from RealmObject even if it only has fields marked with @Ignore , which made me somewhat sad.
A ray of hope
However, just because you can’t inherit from anything other than RealmObject (while still being able to implement interfaces, of course), doesn’t mean you can’t just do a DIY base observable yourself! :)
There’s some boilerplate code here from BaseObservable that we just copy and ignore afterwards, put @Bindable on the getters, and allow data-binding to occur on unmanaged objects in the setters (after all, you can’t write a RealmObject outside of a transaction, and you’re not using synchronous transactions on the UI thread, right?)
Afterwards, all we need to do is make it work for managed RealmObjects as well. That’s what RealmDataBinding interface is for.
Using the power of RealmChangeListeners, we’ll be notified if anything in this class has been modified, and we assume that all properties have been modified. Now we can bind the managed RealmObject to a layout, add this special change listener to it, and voila’ auto-updates to the view-binding!
Working with lists (RecyclerViews)
Now that we can databind one element with reliable change notifications, we should be able to do this with RecyclerViews.
Luckily, we actually don’t need almost any of this magic for that to work. Because the RealmResults has its own RealmChangeListener when used with RealmRecyclerViewAdapter, we don’t need to bind change listeners to the elements themselves (when using managed results).
We can just create a RecyclerView and use the right adapter for it.
And the important parts, actually making the RecyclerView work — we need a ViewHolder that can bind from DataBinding:
Then a View that binds a Post
And then the Adapter that actually binds the Views with the proper RealmObjects
And it’s done! Now our RecyclerView’s items are bound with data binding.
With some boilerplate in our RealmObject, we were able to bind it to view using Data Binding library for Android.
Technically, this is more a proof of concept if anything, I hadn’t used data binding before, but hey, it works! :D
The code shown here is available in my realm-databind-experiment repository.